Это один из способов, которым это обычно делается.
array.each_with_object({}) {|g,h| h.update(g[:name]=>g) {|_,o,n|
o.merge(count: o[:count] + n[:count]) } }.values
#=> [{:id=>1, :name=>"name", :count=>1},
# {:id=>1, :name=>"new name", :count=>1}]
Используется форма Hash # update (он же merge!
), который использует блок для определения значений ключей, которые присутствуют в обоих объединяемых хэшах.
См. Документацию для определения трех блочных переменных, _
, o
и n
. Первый из них содержит общий ключ. Обычной практикой является использование _
для переменных блока, которые не используются в расчете блока.
Обратите внимание, что получатель values
выглядит следующим образом.
array.each_with_object({}) {|g,h| h.update(g[:name]=>g) {|_,o,n|
o.merge(count: o[:count] + n[:count]) } }
#=> {"name"=>{:id=>1, :name=>"name", :count=>2},
# "new name"=>{:id=>1, :name=>"new name", :count=>1}}