tags:

views:

37

answers:

4

I'm trying to zip 3 arrays into a hash. The hash is coming up empty, though. Here's sample code to reproduce using Ruby 1.9:

>> foo0 = ["a","b"]
=> ["a", "b"]
>> foo1 = ["c","d"]
=> ["c", "d"]
>> foo2 = ["e", "f"]
=> ["e", "f"]
>> h = Hash[foo0.zip(foo1, foo2)]
=> {}

I'd like to zip these and then do something like:

h.each_pair do |letter0, letter1, letter2|
   # process letter0, letter1
end
A: 

Hash[] doesn't work quite like you're assuming. Instead, try this:

>> Hash[*foo0, *foo1, *foo2]
=> {"a"=>"b", "c"=>"d", "e"=>"f"}

or, my preferred approach:

>> Hash[*[foo0, foo1, foo2].flatten]
=> {"a"=>"b", "c"=>"d", "e"=>"f"}

Basically, Hash[] is expecting an even number of arguments as in Hash[key1, val1, ...]. The splat operator * is applying the arrays as arguments.

Peter
+1  A: 

It's not clear what you expect the output to be but the [] operator of the Hash class is intended to take an even number of arguments and return a new hash where each even numbered argument is the key for the corresponding odd numbered value.

For example, if you introduce foo3 = ["d"] and you want to get a hash like {"a"=>"b", "c"=>"d"} you could do the following:

>> Hash[*foo0.zip(foo1, foo2, foo3).flatten]
=> {"a"=>"b", "c"=>"d"}
maerics
A: 

It looks like foo0.zip(foo1,foo2) generates: [["a", "b", "c"]]

Which is not an acceptable input for Hash[]. You need to pass it a flat array.

RyanTM
A: 

you don't need Hash for what you are trying to accomplish, zip does it for you

foo0.zip(foo1, foo2) do |f0, f1, f2|
  #process stuff here
end
Matt Briggs