Converting an array of keys and an array of values into a hash in Ruby

15,649

Solution 1

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]

Solution 2

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}

Solution 3

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}
Share:
15,649
Paige Ruten
Author by

Paige Ruten

Updated on June 14, 2022

Comments

  • Paige Ruten
    Paige Ruten about 2 years

    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
    
  • Kyle Cronin
    Kyle Cronin about 15 years
    So Hash[keys.zip(values)] then?
  • Paige Ruten
    Paige Ruten about 15 years
    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...
  • Brian Campbell
    Brian Campbell about 15 years
    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.
  • allyourcode
    allyourcode about 15 years
    This is great. Shame that you have to * and flatten the zip in older versions of Ruby though :(