Суммируйте значения в хешах - PullRequest
2 голосов
/ 16 февраля 2011
array1 = { "d1" => 2, "d2" => 3}
array2 = { "d1" => 3, "d3" => 10}

Я хочу это:
array3 = { "d1" => 5, "d2" => 3, "d3" => 10}

Я попробовал это, это не работает.я получаю сообщение об ошибке: "NoMethodError: неопределенный метод` + 'для nil: NilClass "

array3 = {}
array1.each {|key, count| array3[key] += count}
array2.each {|key, count| array3[key] += count}

Ответы [ 4 ]

4 голосов
/ 16 февраля 2011

намного проще

=> 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}

недокументировано в core-1.8.7, но вы можете прочитать подробнее здесь: http://www.ruby -doc.org / core / classes / Hashsrc / M000759.html

работает на обеих версиях

4 голосов
/ 16 февраля 2011

Вы получаете ошибку, потому что array1.each пытается получить доступ к array3['d1'], который еще не существует, поэтому он возвращает nil в качестве значения. Вам просто нужно определить array3 чуть более конкретно, используя Hash.new, чтобы сказать ему назначить 0 всем клавишам по умолчанию.

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

Будьте осторожны, продвигаясь вперед: объект, который вы передаете в качестве значения по умолчанию, может быть изменен, поэтому, если вы напишите my_hash = Hash.new(Array.new); my_hash[:some_key] << 3, тогда все ключи , получающие значение по умолчанию, будут использовать один и тот же объект , Это одна из тех странных ошибок в Ruby, и вы хотели бы использовать блочную версию Hash.new в этом случае.

1 голос
/ 16 февраля 2011

Пользователь, вы должны инициализировать ключ для несуществующих значений во втором массиве:

irb(main):007:0> array1 = {"d1" => 2, "d2" => 3}
=> {"d1"=>2, "d2"=>3}
irb(main):008:0> array2 = {"d1" => 3, "d3" => 10}
=> {"d1"=>3, "d3"=>10}
irb(main):009:0> array3 = {}
=> {}
irb(main):010:0> array1.each {|key, count| array3[key] = (array3[key] || 0) + count}
=> {"d1"=>2, "d2"=>3}
irb(main):011:0> array2.each {|key, count| array3[key] = (array3[key] || 0) + count}
=> {"d1"=>3, "d3"=>10}
irb(main):012:0> array3
=> {"d1"=>5, "d2"=>3, "d3"=>10}
irb(main):013:0> 
0 голосов
/ 26 марта 2015

Если все ключи в вашем хэше , а не целые числа, вы можете использовать этот трюк, который использует тот факт, что string.to_i дает ноль

hash.to_a.flatten.inject{|sum, n| sum.to_s.to_i + n.to_s.to_i }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...