I like @MarkThomas answer best, but for speed and memory efficiency I suggest:
flatter = {}.tap{ |h| original.values.each{ |h2| h.merge!(h2) } }
Benchmarking 200,000 iterations of current answers shows that this is the fastest:
user system total real Phrogz 0.710000 0.020000 0.730000 ( 0.728706) Joshua Creek 0.830000 0.010000 0.840000 ( 0.830700) Mark Thomas symbol 1.460000 0.020000 1.480000 ( 1.486463) Mark Thomas to_proc 1.540000 0.030000 1.570000 ( 1.565354) Tim Peters 1.650000 0.030000 1.680000 ( 1.678283)
Since the comment @ tokland- original.values.reduce(:update) -modulates the original hash, we cannot compare it directly with other methods. However, if we modify all the tests to put a duplicate of the first hash back in the original each iteration, @tokland's answer will become the fastest, although still not as fast as mine:
user system total real tokland destroyer 0.760000 0.010000 0.770000 ( 0.772774) Phrogz 1.020000 0.020000 1.040000 ( 1.034755) Joshua Creek 1.060000 0.000000 1.060000 ( 1.063874) Mark Thomas symbol 1.780000 0.040000 1.820000 ( 1.816909) Mark Thomas to_proc 1.790000 0.030000 1.820000 ( 1.819014) Tim Peters 1.800000 0.040000 1.840000 ( 1.827984)
If you need absolute speed, and OK, to change the initial values, use @tokland's answer. If you do this and want to keep the original unmixed hashes intact, you can:
first_k,orig_v = original.each{ |k,v| break [k,v.dup] } merged = original.values.reduce(:update) original[first_k] = orig_v
Please note that the title of the question indicates traverse ; if you really do not want to combine the values ββ- if you want to double-click the duplicate key instead of the last in the winnings, just do:
original.values.each{ |h| h.each{ |k,v|