For example
Given an array:
array = [[:a,:b],[:a,:c],[:c,:b]]
Return the following hash:
hash = { :a => [:b,:c] , :c => [:b] }
hash = Hash[array]
overwrites previous associations, producing:
hash = { :a => :c , :c => :b }
Given an array:
array = [[:a,:b],[:a,:c],[:c,:b]]
Return the following hash:
hash = { :a => [:b,:c] , :c => [:b] }
hash = Hash[array]
overwrites previous associations, producing:
hash = { :a => :c , :c => :b }
This can be done fairly succinctly using
each_with_object
.Demonstrating in
irb
:EDIT: In Ruby 2.1+, you can use Array#to_h
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.
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)
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)
Using functional baby steps:
Using imperative style programming:
As an imperative one-liner:
Or using everyone's favorite
inject
:If you really want to have single values not collided as an array, you can either un-array them as a post-processing step, or use a different hash accumulation strategy that only creates an array upon collision. Alternatively, wrap your head around this: