How to merge two hashes that have same keys in ruby

18,575

Solution 1

Use Hash#merge or Hash#merge!:

a = {a: 1, b: 2, c: 3}
b = {a: 2, c: 4, b: 3}
a.merge!(b) { |k, o, n| o + n }
a # => {:a=>3, :b=>5, :c=>7}

The block is called with key, old value, new value. And the return value of the block is used as a new value.

Solution 2

If you're using Active Support (Rails), which adds Hash#transform_values, I really like this easy-to-read solution when you have n hashes:

hashes = [hash_1, hash_2, hash_3] # any number of hashes
hashes.flat_map(&:to_a).group_by(&:first).transform_values { |x| x.sum(&:last) }

Share:
18,575

Related videos on Youtube

ironsand
Author by

ironsand

こんにちは。言語関係のサービスを作りたく勉強中です。よろしくお願いします。

Updated on July 15, 2022

Comments

  • ironsand
    ironsand almost 2 years

    I have a two hashes that should have same keys like:

    a = {a: 1, b: 2, c: 3}
    b = {a: 2, b: 3, c: 4}
    

    And I want to sum up each values like this:

    if a.keys == b.keys
      a.values.zip(b.values).map{|a, b| a+b}
    end
    

    But this code doesn't work if the order of keys are different like b = {a: 2, c: 4, b: 3}.

    How can I write the code taking into account about order of keys?

  • Arup Rakshit
    Arup Rakshit almost 10 years
    I like #merge with block. If I get a chance, I use it.
  • Henning Hall
    Henning Hall over 5 years
    Getting this error: [!] undefined method `+' for #<Hash:0x007fcea7130330>
  • falsetru
    falsetru over 5 years
    @HenningHall, ideone.com/yKrqLc Seems like you're using old version of ruby where Hash#merge does not exist. Not sure since which version it's available, but according to documentation, it should be there for 1.8.6+
  • Giridharan
    Giridharan about 5 years
    i am struggle with my case how to do it it plz help me if anyone knows. 1)a = {"Additional Options"=>{"Break Fast"=>100.0,"Lunch"=>300.0}, "Discount"=>{}, "Coupon"=>{"cou"=>10}} 2) b = {"Additional Options"=>{"Break Fast"=>100.0}, "Discount"=>{}, "Coupon"=>{"cou"=>10.0}} My Expectation is Like This =>{"Additional Options"=>{"Break Fast"=>200.0,"Lunch"=>300.0}, "Discount"=>{}, "Coupon"=>{"cou"=>10.0}
  • falsetru
    falsetru about 5 years
    @giridharan, Please post a separated question.
  • Giridharan
    Giridharan about 5 years
    My question limits reached😥😥