22

I have two arrays like this:

keys = ['a', 'b', 'c']
values = [1, 2, 3]

Is there a simple way in Ruby to convert those arrays into the following hash?

{ 'a' => 1, 'b' => 2, 'c' => 3 }

Here is my way of doing it, but I feel like there should be a built-in method to easily do this.

def arrays2hash(keys, values)
  hash = {}
  0.upto(keys.length - 1) do |i|
      hash[keys[i]] = values[i]
  end
  hash
end

5 Answers 5

56

The following works in 1.8.7:

keys = ["a", "b", "c"]
values = [1, 2, 3]
zipped = keys.zip(values)
=> [["a", 1], ["b", 2], ["c", 3]]
Hash[zipped]
=> {"a"=>1, "b"=>2, "c"=>3}

This appears not to work in older versions of Ruby (1.8.6). The following should be backwards compatible:

Hash[*keys.zip(values).flatten]
Sign up to request clarification or add additional context in comments.

4 Comments

So Hash[keys.zip(values)] then?
Thanks, the zip method is probably what I need... but the "Hash[zipped]" part is giving me an error in Ruby 1.8.6: "ArgumentError: odd number of arguments for Hash". And I just can't figure out another simple way of changing 'zipped' into a hash...
Hmm. I'm using 1.8.7. It looks like this might have been introduced in 1.8.7. I'll edit the answer for a backwards-compatible version.
This is great. Shame that you have to * and flatten the zip in older versions of Ruby though :(
10

Another way is to use each_with_index:

hash = {}
keys.each_with_index { |key, index| hash[key] = values[index] }

hash # => {"a"=>1, "b"=>2, "c"=>3}

Comments

10

The same can be done using Array#transpose method. If you are using Ruby version >= 2.1, you can take the advantage of the method Array#to_h, otherwise use your old friend, Hash::[]

keys = ['a', 'b', 'c']
values = [1, 2, 3]
[keys, values].transpose.to_h
# => {"a"=>1, "b"=>2, "c"=>3}
Hash[[keys, values].transpose]
# => {"a"=>1, "b"=>2, "c"=>3}

2 Comments

Fantastic stuff. Thanks. I did a little edit to cleanup the code and highlight which one you use, depending on the version of Ruby you have.
Any idea if this is preferable to the .zip method shown below? e.g. more performant, etc.?
0

Try this, this way the latter one d will overwrite the former one c

irb(main):001:0>  hash = Hash[[[1,2,3,3], ['a','b','c','d']].transpose]
=> {1=>"a", 2=>"b", 3=>"d"}
irb(main):002:0>

Comments

0

In current Ruby keys.zip(values).to_h is probably the most readable short solution.

References:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.