Forum: Ruby Hash merge question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
8c2651465c0fa8d0a6d418cc50026c99?d=identicon&s=25 Random Qu (random-query)
on 2009-04-20 08:57
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
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (candlerb)
on 2009-04-20 10:26
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.
8a6ac97a9f46ba8ee2be40d4d6a7fba1?d=identicon&s=25 Florian Kaufmann (Guest)
on 2009-04-20 11:17
(Received via mailing list)
#!/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]]}
8c2651465c0fa8d0a6d418cc50026c99?d=identicon&s=25 Random Qu (random-query)
on 2009-04-20 11:31
Thanks Florian!
That's what I was after.
Cf7cd97cdc8ed7d4ae92965b24f0dfad?d=identicon&s=25 Stefan Rusterholz (apeiros)
on 2009-04-20 13:33
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 Kaufmann 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]]}
This topic is locked and can not be replied to.