White Elephant White Elephant - 2 years ago 162
Ruby Question

Merging multi-dimensional hashes in Ruby

I have two hashes which have a structure something similar to this:

hash_a = { :a => { :b => { :c => "d" } } }
hash_b = { :a => { :b => { :x => "y" } } }

I want to merge these together to produce the following hash:

{ :a => { :b => { :c => "d", :x => "y" } } }

The merge function will replace the value of :a in the first hash with the value of :a in the second hash. So, I wrote my own recursive merge function, which looks like this:

def recursive_merge( merge_from, merge_to )
merged_hash = merge_to
first_key = merge_from.keys[0]
if merge_to.has_key?(first_key)
merged_hash[first_key] = recursive_merge( merge_from[first_key], merge_to[first_key] )
merged_hash[first_key] = merge_from[first_key]

But I get a runtime error:
can't add a new key into hash during iteration
. What's the best way of going about merging these hashes in Ruby?

Answer Source

If you change the first line of recursive_merge to

merged_hash = merge_to.clone

it works as expected:

recursive_merge(hash_a, hash_b)    
->    {:a=>{:b=>{:c=>"d", :x=>"y"}}}

Changing the hash as you move through it is troublesome, you need a "work area" to accumulate your results.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download