Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add up values in hashes

Tags:

ruby

array1 = { "d1" => 2, "d2" => 3}
array2 = { "d1" => 3, "d3" => 10}

i want this:
array3 = { "d1" => 5, "d2" => 3, "d3" => 10}

i tried this, it doesn't work. i am getting the error: "NoMethodError: undefined method `+' for nil:NilClass"

array3 = {}
array1.each {|key, count| array3[key] += count}
array2.each {|key, count| array3[key] += count}
like image 559
user612308 Avatar asked Dec 08 '25 06:12

user612308


2 Answers

You're getting the error because array1.each tries to access array3['d1'], which doesn't exist yet, so it returns nil as the value. You just need to define array3 a bit more specifically, using Hash.new to tell it to assign 0 to all keys by default.

array3 = Hash.new(0)
array1.each {|key, count| array3[key] += count}
array2.each {|key, count| array3[key] += count}

Be careful going forward, though: the object you pass as the default value can be modified, so if you were to write my_hash = Hash.new(Array.new); my_hash[:some_key] << 3 then all keys that receive a default value will share the same object. This is one of those strange gotchas in Ruby, and you would want to use the block version of Hash.new in that case.

like image 131
wersimmon Avatar answered Dec 09 '25 21:12

wersimmon


it is much more simplier

=> h1 = { "a" => 100, "b" => 200 }
{"a"=>100, "b"=>200}
=> h1 = { "a" => 100, "b" => 200 }
{"b"=>254, "c"=>300}
=> h1.merge(h2) {|key, oldval, newval| newval + oldval}
{"a"=>100, "b"=>454, "c"=>300}

it was undocumented in core-1.8.7 but you can read more here: http://www.ruby-doc.org/core/classes/Hash.src/M000759.html

it works on both versions

like image 40
avsej Avatar answered Dec 09 '25 22:12

avsej



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!