"adding" two hashes

#1

Hi,

I’m wondering if it is possible to “add” the values of two hashes
together. Suppose I had:

hash1 = {:key_one=>100, :key_two=>200}
hash2 = {:key_two=>300, :key_three=>400}

I’d like to “add” the hashes together so that I get

result => {:key_one=>100, :key_two=>500, :key_three=>400}

Do I need to write my own function to parse through each hash’s keys?
Is there a built-in way to do this?

Thanks!

#2

On Wed, Jan 28, 2009 at 11:07 AM, Bryson S. removed_email_address@domain.invalid
wrote:

Do I need to write my own function to parse through each hash’s keys?
Is there a built-in way to do this?

You can try Hash#merge:

irb(main):007:0> a = {:a => 1}
=> {:a=>1}
irb(main):008:0> b = {:b => 2}
=> {:b=>2}
irb(main):009:0> c = a.merge( b )
=> {:a=>1, :b=>2}

Note that if you have duplicate keys, the values in b will override
the values in a.

Ben

#3

On Jan 28, 2009, at 2:07 PM, Bryson S. wrote:

result => {:key_one=>100, :key_two=>500, :key_three=>400}

Do I need to write my own function to parse through each hash’s keys?
Is there a built-in way to do this?

Thanks!

irb> hash1 = {:key_one=>100, :key_two=>200}
=> {:key_two=>200, :key_one=>100}
irb> hash2 = {:key_two=>300, :key_three=>400}
=> {:key_two=>300, :key_three=>400}

irb> result = hash1.merge(hash2) {|key,val1,val2| val1+val2}
=> {:key_two=>500, :key_three=>400, :key_one=>100}

You only have to write the block that deals with the duplicates for
‘key’

-Rob

Rob B. http://agileconsultingllc.com
removed_email_address@domain.invalid

#4

Bryson S. wrote:

Hi,

I’m wondering if it is possible to “add” the values of two hashes
together. Suppose I had:

hash1 = {:key_one=>100, :key_two=>200}
hash2 = {:key_two=>300, :key_three=>400}

I’d like to “add” the hashes together so that I get

result => {:key_one=>100, :key_two=>500, :key_three=>400}

Do I need to write my own function to parse through each hash’s keys?
Is there a built-in way to do this?

Thanks!

No built-in way, but it would be easy to use hash1.each_key to iterate
over the keys of hash1. For every key in hash1, get its value for that
key from hash1 and hash2, add the two values and store the sum as the
value of that key in result.

The question is, what happens if there’s a key in hash1 that isn’t in
hash2, or vice versa?

#5

On Jan 28, 2009, at 2:31 PM, Tim H. wrote:

value of that key in result.

The question is, what happens if there’s a key in hash1 that isn’t in
hash2, or vice versa?

In case it was missed the first time:

irb> result = hash1.merge(hash2) {|key,val1,val2| val1+val2}
=> {:key_two=>500, :key_three=>400, :key_one=>100}

You only have to write the block that deals with the duplicates for
‘key’

-Rob

Rob B. http://agileconsultingllc.com
removed_email_address@domain.invalid

#6

Yeah it’s awesome but i am struggle with my case if you have any ideas please share to me i am very new to ruby … OK let’s explain my problem. i have a two hashes i want to merge two hashes my hashes like key pair value, But values is also hash type so only struggle in this case
a = {"Additional Options"=>{"Break Fast"=>100.0,"Lunch"=>300.0}, "Discount"=>{}, "Coupon"=>{"cou"=>10}}
b = {"Additional Options"=>{"Break Fast"=>100.0}, "Discount"=>{}, "Coupon"=>{"cou"=>10.0}}
i am trying to merge a.merge(b){ |k,v1,v2|v1+v2} i know this wrong but really i dont no how do this please me anyone…
My Expectation is Like This
{"Additional Options"=>{"Break Fast"=>200.0,"Lunch"=>300.0}, "Discount"=>{}, "Coupon"=>{"cou"=>10.0}
Thanks Advance Developers…

#7

Even easier.

hash_name.each {|key1 ,key2| key1.to_i + key2.to_i}

#8

Wait I got what you were trying to do lol. Sorry haven’t had my coffee yet…

A very easy way to do this

hash1= {:key1 => 100 , :key2 => 200}
hash2 ={:key2 => 400 , :key3 => 300}
hash3 = hash2.delete(“key2”) , hash1.merge(hash2)


#9

i see you’re trying to total up the keys of the “Addition Options” hash. this may work:

additional_options = "Additional Options"
a[additional_options] = [a, b].map({ |h| h[additional_options].to_a })
  .flatten
  .group_by({ |t| t[0] })
  .map({ |t| [t[0], t[1].reduce(0, :+)] })
  .to_h

merging all keys

a.merge(b) do |key, p_val, n_val|
  both_hashes? = p_val.class ==  Hash && n_val.class == Hash
  is_additional_options? = key == "Additional Options"

  return n_val unless both_hashes?
  
  if is_additional_options?
    p_val.merge(n_val) { |k, p, n| p +n }
  else
    p_val.merge(n_val)
  end
end

sorry, so many edits…

#10

Thanks Guys!! Finally completed.it’s very easy …:sweat_smile::sweat_smile::sweat_smile:
a = {"Additional Options"=>{"Break Fast"=>300.0,"Lunch"=>500.0}, "Discount"=>{}, "Coupon"=>{"cou"=>10}}

b = {"Additional Options"=>{"Break Fast"=>100.0,"Lunch"=>10}, "Discount"=>{}, "Coupon"=>{"cou"=>20.0}}

c = a.merge(b){|key,val1,val2|val1.merge(val2){|k,v1,v2|v1+v2}}
puts c
=>{"Additional Options"=>{"Break Fast"=>400.0, "Lunch"=>510.0}, "Discount"=>{}, "Coupon"=>{"cou"=>30.0}}
Thanks…your support…

1 Like