Convert array of 2-element arrays into a hash, where duplicate keys append additional values

后端 未结 4 1015
感动是毒
感动是毒 2020-12-01 05:03

For example

Given an array:

array = [[:a,:b],[:a,:c],[:c,:b]]

Return the following hash:

hash = { :a => [:b,:c         


        
4条回答
  •  情话喂你
    2020-12-01 05:41

    EDIT: In Ruby 2.1+, you can use Array#to_h

    pry(main)> [[:a,:b],[:a,:c],[:c,:b]].to_h
    => {:a=>:c, :c=>:b}
    

    END EDIT

    The public [] method on the Hash class accepts a key-value pair array and returns a hash with the first element of the array as key and the second as value.

    The last value in the key-value pair will be the actual value when there are key duplicates.

    Hash[[[:a,:b],[:a,:c],[:c,:b]]]
        => {:a=>:c, :c=>:b}
    

    This syntax is valid in 1.9.3+ ; I'm not sure about earlier Ruby versions (it's not valid in 1.8.7)

    ref: http://www.ruby-doc.org/core-2.1.0/Hash.html#method-c-5B-5D

    Another interesting way of doing it would be using the inject method: (obviously the method above is more succinct and recommended for this specific problem)

    [ [:a, :b], [:a, :c], [:c, :b] ].inject({}) { |memo, obj| 
       memo[obj.first] = obj.last
       memo 
    }
    
    => {:a=>:c, :c=>:b}
    

    inject iterates over the enumerable, your array in this case, starting with the injected parameter, in this case the empty hash {}.

    For each object in the enumerable, the block is called with the variables memo and obj:

    • obj is the current object in the array

    • memo is the value that has been returned by your block's last iteration (for the first iteration, it's what you inject)

提交回复
热议问题