Hash merge question


#1

Hi All,
I have 2 hashes like this.

h1 = {
a1 => [y1, y2, y3],
a2 => [y4, y5, y6]
}
h2 = {
a2 => [z1, z2, z3],
a3 => [z4, z5, z6]
}

And I nedd to merge them into something like this.

h = {
a1 => [[y1, y2, y3] , []]
a2 => [[y4, y5, y6] , [z1, z2, z3]]
a3 => [[] , [z4, z5, z6]]
}

What’s the best way of doing this?
Thanks a lot for your help!

  • RQ

#2

Random Qu wrote:

What’s the best way of doing this?

Why don’t you show us what you’ve done so far, whether or not it works,
and then we can suggest whether there are improvements which can be
made.

Regards,

Brian.


#3

#!/usr/bin/ruby
h1 = {
:a1 => [:y1, :y2, :y3],
:a2 => [:y4, :y5, :y6]
}
h2 = {
:a2 => [:z1, :z2, :z3],
:a3 => [:z4, :z5, :z6]
}
h = {}
(h1.keys + h2.keys).each {|k| h[k] = [[],[]] }
h = h1.to_a.inject(h) { |i,kv| i[kv[0]][0] = kv[1]; i }
h = h2.to_a.inject(h) { |i,kv| i[kv[0]][1] = kv[1]; i }
p h

gives

{:a2=>[[:y4, :y5, :y6], [:z1, :z2, :z3]], :a1=>[[:y1, :y2, :y3],
[]], :a3=>[[], [:z4, :z5, :z6]]}


#4

Thanks Florian!
That’s what I was after.


#5

A little bit simpler:

result = {}
(h1.keys | h2.keys).each { |key| result[key] = [(h1[key] || []),
(h2[key] || []) }

No need to abuse inject.

Regards
Stefan

Florian K. wrote:

#!/usr/bin/ruby
h1 = {
:a1 => [:y1, :y2, :y3],
:a2 => [:y4, :y5, :y6]
}
h2 = {
:a2 => [:z1, :z2, :z3],
:a3 => [:z4, :z5, :z6]
}
h = {}
(h1.keys + h2.keys).each {|k| h[k] = [[],[]] }
h = h1.to_a.inject(h) { |i,kv| i[kv[0]][0] = kv[1]; i }
h = h2.to_a.inject(h) { |i,kv| i[kv[0]][1] = kv[1]; i }
p h

gives

{:a2=>[[:y4, :y5, :y6], [:z1, :z2, :z3]], :a1=>[[:y1, :y2, :y3],
[]], :a3=>[[], [:z4, :z5, :z6]]}