как объединить массив суммирующих хешей по значению? - PullRequest
0 голосов
/ 28 апреля 2019

У меня есть массив хэшей

[{:id=>1, :book=>{:title=>"title1", :desc=>"title1", :author=>"title1"}, :pages=>10},
 {:id=>1, :book=>{:title=>"title1", :desc=>"title1", :author=>"title1"}, :pages=>10},
 {:id=>2, :book=>{:title=>"title2", :desc=>"title2", :author=>"title2"}, :pages=>30}]

Как мне суммировать значение pages, оставляя только уникальные ключи?Например:

1006 *

Ответы [ 2 ]

3 голосов
/ 28 апреля 2019

Давайте сгруппируем по id и отобразим каждый результат в структуру, где страницы являются суммой всех страниц для этого идентификатора

array.
  group_by { |item| item[:id] }.
  map do |id, items| 
    page_sum = items.sum { |i| i[:pages] }
    Hash[:id, id, :book, items.first[:book], :pages, page_sum] 
  end
2 голосов
/ 28 апреля 2019
arr = [
  {:id=>1, :book=>{:title=>"title1", :desc=>"title1", :author=>"title1"}, :pages=>10},
  {:id=>1, :book=>{:title=>"title1", :desc=>"title1", :author=>"title1"}, :pages=>10},
  {:id=>2, :book=>{:title=>"title2", :desc=>"title2", :author=>"title2"}, :pages=>30}
]

arr.each_with_object({}) do |g,h|
  h.update(g[:id]=>g) { |_,o,n| o.merge(pages: o[:pages] + n[:pages]) }
end.values
  #=> [{:id=>1, :book=>{:title=>"title1", :desc=>"title1", :author=>"title1"}, :pages=>30},
  #    {:id=>2, :book=>{:title=>"title2", :desc=>"title2", :author=>"title2"}, :pages=>30}] 

Обратите внимание, что получатель values равен

{1=>{:id=>1, :book=>{:title=>"title1", :desc=>"title1", :author=>"title1"}, :pages=>30},
 2=>{:id=>2, :book=>{:title=>"title2", :desc=>"title2", :author=>"title2"}, :pages=>30}} 

Используется форма Hash # update (он же merge!), который использует блок

{ |_,o,n| o.merge(pages: o[:pages] + n[:pages]) }

для определения значений ключей (переменная блока _), которые присутствуют в обоих объединяемых хэшах.См. Документ для объяснения переменных блока o и n.

Hash#update и Enumerable # group_by - это два метода, к которым обычно обращаются при решении проблемэтот вид.Любой может быть использован.Они примерно одинаковы по эффективности, поэтому выбор во многом зависит от личных предпочтений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...