在Ruby中对哈希数组中的值求和

在Ruby中对哈希数组中的值求和,ruby,Ruby,我有以下哈希数组: books = [ {'author' => 'John Doe', 'month' => 'June', 'sales' => 500}, {'author' => 'George Doe', 'month' => 'June', 'sales' => 600}, {'author' => 'John Doe', 'month' => 'July', 'sales' => 700}, {'author'

我有以下哈希数组:

books = [
  {'author' => 'John Doe', 'month' => 'June', 'sales' => 500},
  {'author' => 'George Doe', 'month' => 'June', 'sales' => 600},
  {'author' => 'John Doe', 'month' => 'July', 'sales' => 700},
  {'author' => 'George Doe', 'month' => 'July', 'sales' => 800}
]
在此基础上,如何获得具有以下内容的数组:

[
  {'author' => 'John Doe', 'total_sales' => 1200},
  {'author' => 'George Doe', 'total_sales' => 1400}
]

您可以使用
Enumerable#group_by
获取数组的数组。然后可以使用
Enumerable#reduce
Hash#merge
合并每个数组的散列

group_books=books.group_by{h | h['author']}.values
结果=组_books.map do | ary|
ary.reduce do| new_hash,h|
new|hash.merge(h){| k,v1,v2 | k=='sales'?v1+v2:v1}
结束
结束
编辑:我忘了用
Hash\delete
删除键
month

result.map { |h| h.delete('month') }

您可以使用
Enumerable#group_by
获取数组的数组。然后可以使用
Enumerable#reduce
Hash#merge
合并每个数组的散列

group_books=books.group_by{h | h['author']}.values
结果=组_books.map do | ary|
ary.reduce do| new_hash,h|
new|hash.merge(h){| k,v1,v2 | k=='sales'?v1+v2:v1}
结束
结束
编辑:我忘了用
Hash\delete
删除键
month

result.map { |h| h.delete('month') }

您可以将
每个\u与\u对象一起使用
,并使用适当的默认值:

default = Hash.new {|h,k| h[k] = { 'author' => k, 'total_sales' => 0 } }
books.each_with_object(default) do |h, memo|
  memo[h['author']]['total_sales'] += h['sales']
end.values
产出:

[
  {"author"=>"John Doe", "total_sales"=>1200}, 
  {"author"=>"George Doe", "total_sales"=>1400}
]

您可以将
每个\u与\u对象一起使用
,并使用适当的默认值:

default = Hash.new {|h,k| h[k] = { 'author' => k, 'total_sales' => 0 } }
books.each_with_object(default) do |h, memo|
  memo[h['author']]['total_sales'] += h['sales']
end.values
产出:

[
  {"author"=>"John Doe", "total_sales"=>1200}, 
  {"author"=>"George Doe", "total_sales"=>1400}
]
您可以使用(aka
merge!
)的形式,使用块来确定合并的两个哈希中存在的键的值:

books.each_with_object({}) do |g,h|
  h.update(g['author']=>g['sales']) { |_,o,n| o+n }
end.map { |k,v| { 'author'=>k, 'total_sales'=>v } } 
  #=> [{"author"=>"John Doe", "total_sales"=>1200},
  #    {"author"=>"George Doe", "total_sales"=>1400}] 
有关块变量
\uu
o
n
的说明,请参见文档。(我对公共键使用了
,主要是向读者发出信号,表示它不用于块计算,这是一种常见的Ruby约定。)

考虑在构建哈希后停止:

books.each_with_object({}) do |g,h|
  h.update(g['author']=>g['sales']) { |_,o,n| o+n }
end
  #=> {"John Doe"=>1200, "George Doe"=>1400}  
您可以使用(aka
merge!
)的形式,使用块来确定合并的两个哈希中存在的键的值:

books.each_with_object({}) do |g,h|
  h.update(g['author']=>g['sales']) { |_,o,n| o+n }
end.map { |k,v| { 'author'=>k, 'total_sales'=>v } } 
  #=> [{"author"=>"John Doe", "total_sales"=>1200},
  #    {"author"=>"George Doe", "total_sales"=>1400}] 
有关块变量
\uu
o
n
的说明,请参见文档。(我对公共键使用了
,主要是向读者发出信号,表示它不用于块计算,这是一种常见的Ruby约定。)

考虑在构建哈希后停止:

books.each_with_object({}) do |g,h|
  h.update(g['author']=>g['sales']) { |_,o,n| o+n }
end
  #=> {"John Doe"=>1200, "George Doe"=>1400}  

我会用这样的方式:

sales = ->(hash) { hash['sales'] }
books.group_by { |book| book.slice('author') }
     .map { |result, books| result.merge('total_sales' => books.sum(&sales)) }
#=> [
#   {"author"=>"John Doe", "total_sales"=>1200},
#   {"author"=>"George Doe", "total_sales"=>1400}
# ]
代码主要是为自己说话。我先吃了一份杂烩。然后是
书籍
中的销售值


我已将
sum
块提取到a中,并将其保存在
sales
变量中,以避免
map
块与嵌套块混淆。

我将使用以下方法:

sales = ->(hash) { hash['sales'] }
books.group_by { |book| book.slice('author') }
     .map { |result, books| result.merge('total_sales' => books.sum(&sales)) }
#=> [
#   {"author"=>"John Doe", "total_sales"=>1200},
#   {"author"=>"George Doe", "total_sales"=>1400}
# ]
代码主要是为自己说话。我先吃了一份杂烩。然后是
书籍
中的销售值


我已将
sum
块提取到a,并将其保存在
sales
变量中,以避免
map
块与嵌套块混淆。

无需“编辑:”。只是静静地修改你的答案,就像你在编辑你正在写的文章的草稿一样。不需要“编辑:”。只需静静地修改你的答案,就像你在编辑你正在写的文章的草稿一样。默认哈希的使用非常好。默认哈希的使用非常好。请查看“”、“”及其所有链接页面。你研究过这个吗?哪里如果没有帮助,告诉我们原因。你试了什么?如果你不尝试,为什么不呢?如果你做了,你做了什么?我们希望看到您解决此问题的最小尝试。请查看“”和“”及其所有链接页面。你研究过这个吗?哪里如果没有帮助,告诉我们原因。你试了什么?如果你不尝试,为什么不呢?如果你做了,你做了什么?我们希望你尽可能少地解决这个问题。