Search code examples
rubyarrayshashmap

What is the best way to convert an array to a hash in Ruby


In Ruby, given an array in one of the following forms...

[apple, 1, banana, 2]
[[apple, 1], [banana, 2]]

...what is the best way to convert this into a hash in the form of...

{apple => 1, banana => 2}

Solution

  • NOTE: For a concise and efficient solution, please see Marc-André Lafortune's answer below.

    This answer was originally offered as an alternative to approaches using flatten, which were the most highly upvoted at the time of writing. I should have clarified that I didn't intend to present this example as a best practice or an efficient approach. Original answer follows.


    Warning! Solutions using flatten will not preserve Array keys or values!

    Building on @John Topley's popular answer, let's try:

    a3 = [ ['apple', 1], ['banana', 2], [['orange','seedless'], 3] ]
    h3 = Hash[*a3.flatten]
    

    This throws an error:

    ArgumentError: odd number of arguments for Hash
            from (irb):10:in `[]'
            from (irb):10
    

    The constructor was expecting an Array of even length (e.g. ['k1','v1,'k2','v2']). What's worse is that a different Array which flattened to an even length would just silently give us a Hash with incorrect values.

    If you want to use Array keys or values, you can use map:

    h3 = Hash[a3.map {|key, value| [key, value]}]
    puts "h3: #{h3.inspect}"
    

    This preserves the Array key:

    h3: {["orange", "seedless"]=>3, "apple"=>1, "banana"=>2}