Consider this extension to Enumerable:
module Enumerable
def hash_on
h = {}
each do |e|
h[yield(e)] = e
end
h
end
end
It is used like so:
people = [
{:name=>'fred', :age=>32},
{:name=>'barney', :age=>42},
]
people_hash = people.hash_on { |person| person[:name] }
p people_hash['fred'] # => {:age=>32, :name=>"fred"}
p people_hash['barney'] # => {:age=>42, :name=>"barney"}
Is there a built-in function which already does this, or close enough to it that this extension is not needed?
Enumerable.to_h accepts either a sequence of [key, value]
s or a block for converting elements into a Hash
so you can do:
people.to_h {|p| [p[:name], p]}
The block should return a 2-element array which becomes a key-value pair in the returned Hash
. If you have multiple values mapped to the same key, this keeps the last one.
In versions of Ruby earlier than 3, you'll need to convert with map
first before calling to_h
:
people.map {|p| [p[:name], p]}.to_h