Home » Ruby » Array of hashes to hash

Array of hashes to hash

Posted by: admin November 30, 2017 Leave a comment

Questions:

For example, I have array of single hashes

a = [{a: :b}, {c: :d}]

What is best way to convert it into this?

{a: :b, c: :d}
Answers:

You may use

a.reduce Hash.new, :merge

which directly yields

{:a=>:b, :c=>:d}

Note that in case of collisions the order is important. Latter hashes override previous mappings, see e.g.:

[{a: :b}, {c: :d}, {e: :f, a: :g}].reduce Hash.new, :merge   # {:a=>:g, :c=>:d, :e=>:f}

Questions:
Answers:

Those two are equivalent:

total_hash = hs.reduce({}) { |acc_hash, hash| acc_hash.merge(hash) }
total_hash = hs.reduce({}, :merge)

Note that Hash#merge creates a new hash on each iteration, which may be a problem if you are building a big hash. In that case, use update instead:

total_hash = hs.reduce({}, :update)

An alternative approach would be to convert the hashes to pairs and then build the final hash:

total_hash = hs.flat_map(&:to_a).to_h

Questions:
Answers:

You can use .inject:

a.inject(:merge)
#=> {:a=>:b, :c=>:d}

Demonstration

Which initiates a new hash on each iteration from the two merged. To avoid this, you can use destructive :merge!( or :update, which is the same):

a.inject(:merge!)
#=> {:a=>:b, :c=>:d}

Demonstration

Questions:
Answers:

Try this

a.inject({}){|acc, hash| acc.merge(hash)} #=> {:a=>:b, :c=>:d}