Ruby one-liner needed

Here's one taht I know is possible (I'm sure I've seen it somewhere before)

I have 2 arrays and I'd like to change them into a Hash
stuff = ["1", "2", "3"]
Item.column_names.each { |column_name| new_item[column_name] = stuff[?] }

The problem is how to index within the block to move along the stuff array, and how to deal with the fact that most of the time the stuff array is shorter than the column_names array

I'm sure using collect, map of something else ruby-ish that this is more than possible, but I can't find a solution right now

Kev

pairs=%w(a b c d).zip(%w(x y));Hash[*pairs.flatten]
=> {"a"=>"x", "b"=>"y", "c"=>nil, "d"=>nil}

···

On 12/2/05, Kev Jackson <kevin.jackson@it.fts-vn.com> wrote:

I have 2 arrays and I'd like to change them into a Hash

--
Simon Strandgaard

I'm sure there are many ways to do it, here's one:

a=[3,4,5,6]
b=%w{three four five six seven}
res={}
a.length.times {|i| break if i>=b.length; res[a[i]]=b[i]; }

It handles the situation where either array is shorter than the other.

jf

···

On 12/2/05, Kev Jackson <kevin.jackson@it.fts-vn.com> wrote:

Here's one taht I know is possible (I'm sure I've seen it somewhere before)

I have 2 arrays and I'd like to change them into a Hash
stuff = ["1", "2", "3"]
Item.column_names.each { |column_name| new_item[column_name] = stuff[?] }

The problem is how to index within the block to move along the stuff
array, and how to deal with the fact that most of the time the stuff
array is shorter than the column_names array

I'm sure using collect, map of something else ruby-ish that this is more
than possible, but I can't find a solution right now

Kev

--
Johannes Friestad
johannes.friestad@gmail.com

Kev Jackson wrote:

Here's one taht I know is possible (I'm sure I've seen it somewhere before)

I have 2 arrays and I'd like to change them into a Hash
stuff = ["1", "2", "3"]
Item.column_names.each { |column_name| new_item[column_name] = stuff[?] }

The problem is how to index within the block to move along the stuff
array, and how to deal with the fact that most of the time the stuff
array is shorter than the column_names array

stuff = ["1", "2", "3"]
Item.column_names.each_with_index { |column_name, i|
   new_item[column_name] = stuff[i] }

Well, theres lots of ways, but one is to inject the Hash as someone here showed me yesterday:

  items.column_names.inject({}) { |hash, column_name| hash[column_name] = row.shift ; hash }

(I wanted to eliminate the '; hash' at the end of the closure but couldn't find a way yet...)

However, I personally prefer Simon's solution, which can be a real one-liner too :slight_smile:

  Hash[*items.column_names.zip(row).flatten]

···

On Fri, 02 Dec 2005 09:00:30 -0000, Kev Jackson <kevin.jackson@it.fts-vn.com> wrote:

Here's one taht I know is possible (I'm sure I've seen it somewhere before)

I have 2 arrays and I'd like to change them into a Hash
stuff = ["1", "2", "3"]
Item.column_names.each { |column_name| new_item[column_name] = stuff[?] }

The problem is how to index within the block to move along the stuff array, and how to deal with the fact that most of the time the stuff array is shorter than the column_names array

I'm sure using collect, map of something else ruby-ish that this is more than possible, but I can't find a solution right now

Kev

--
Ross Bamford - rosco@roscopeco.remove.co.uk
"\e[1;31mL"

Hi --

Here's one taht I know is possible (I'm sure I've seen it somewhere before)

I have 2 arrays and I'd like to change them into a Hash
stuff = ["1", "2", "3"]
Item.column_names.each { |column_name| new_item[column_name] = stuff[?] }

The problem is how to index within the block to move along the stuff array, and how to deal with the fact that most of the time the stuff array is shorter than the column_names array

I'm sure using collect, map of something else ruby-ish that this is more than possible, but I can't find a solution right now

   a = [1,2,3]
   b = [4,5,6,7,8]
   Hash[*a.zip(b[0,a.size]).flatten
   => {1=>4, 2=>5, 3=>6}

The problem with flatten is that it can be overzealous, but it looks
like you probably don't have nested arrays. If you do, you can get
the flattenx package from RAA and use flatten_once.

David

···

On Fri, 2 Dec 2005, Kev Jackson wrote:

--
David A. Black
dblack@wobblini.net

"Ruby for Rails", forthcoming from Manning Publications, April 2006!

Johannes Friestad wrote:

I'm sure there are many ways to do it, here's one:

a=[3,4,5,6]
b=%w{three four five six seven}
res={}
a.length.times {|i| break if i>=b.length; res[a[i]]=b[i]; }

It handles the situation where either array is shorter than the other.

jf

I'm using...

new_item = Hash.new
Item.column_names.each { |column_name| new_item[column_name] = row.shift }

at the moment and it's working, so I won't replace it with these suggestions

zip was the method I knew about but couldn't remember :slight_smile:

Kev

Hi --

···

On Fri, 2 Dec 2005, David A. Black wrote:

Hi --

On Fri, 2 Dec 2005, Kev Jackson wrote:

Here's one taht I know is possible (I'm sure I've seen it somewhere before)

I have 2 arrays and I'd like to change them into a Hash
stuff = ["1", "2", "3"]
Item.column_names.each { |column_name| new_item[column_name] = stuff[?] }

The problem is how to index within the block to move along the stuff array, and how to deal with the fact that most of the time the stuff array is shorter than the column_names array

I'm sure using collect, map of something else ruby-ish that this is more than possible, but I can't find a solution right now

a = [1,2,3]
b = [4,5,6,7,8]
Hash[*a.zip(b[0,a.size]).flatten
=> {1=>4, 2=>5, 3=>6}

Actually just use the shorter one first and zip won't fill it out with
nils:

   Hash[*a.zip(b).flatten]

David

--
David A. Black
dblack@wobblini.net

"Ruby for Rails", forthcoming from Manning Publications, April 2006!

Hi --

Hi --

Hi --

Here's one taht I know is possible (I'm sure I've seen it somewhere before)

I have 2 arrays and I'd like to change them into a Hash
stuff = ["1", "2", "3"]
Item.column_names.each { |column_name| new_item[column_name] = stuff[?] }

The problem is how to index within the block to move along the stuff array, and how to deal with the fact that most of the time the stuff array is shorter than the column_names array

I'm sure using collect, map of something else ruby-ish that this is more than possible, but I can't find a solution right now

a = [1,2,3]
b = [4,5,6,7,8]
Hash[*a.zip(b[0,a.size]).flatten
=> {1=>4, 2=>5, 3=>6}

Actually just use the shorter one first and zip won't fill it out with
nils:

Hash[*a.zip(b).flatten]

I hereby swear I will stop posting until I am being torn in no more
than ten directions at the same time :slight_smile: In other words: I realize
that you can't just switch them around at will. So you have to decide
whether you're happy to have nils or if you want to truncate the hash
based on available values.

So adapt as needed :slight_smile:

David

P.S. One of the things I've been grappling with today is (the third
day of) intermittent/non-existent Internet service -- and a mysterious
reboot on my server. So I got and read this thread out of order.
Sorry if I reinvented anyone's wheel :slight_smile:

···

On Sat, 3 Dec 2005, David A. Black wrote:

On Fri, 2 Dec 2005, David A. Black wrote:

On Fri, 2 Dec 2005, Kev Jackson wrote:

--
David A. Black
dblack@wobblini.net

"Ruby for Rails", forthcoming from Manning Publications, April 2006!