ruby - 按哈希数组分组
问题描述
对于哈希数组:
array = [{id: 1, name: 'name', count: 2},
{id: 1, name: 'name', count: 1},
{id: 1, name: 'new name', count: 1}]
我想要结果:
[{id: 1, name: 'name', count: 3},
{id: 1, name: 'new name', count: 1}]
我通过以下方式实现了这一目标:
grouped_data = array.each_with_object(Hash.new(0)) do |row, sum|
sum["#{row.fetch(:id)} #{row.fetch(:name)}"] += row.fetch(:count).to_i
end
result = array.uniq.each do |row|
row[:count] = grouped_data["#{row.fetch(:id)} #{row.fetch(:name)}"]
row
end
有没有更优雅的方法来达到预期的效果?
解决方案
这是通常会做的一种方式。
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 (aka 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}}
推荐阅读
- angular - 如何使用 gridOptions 为 ag-grid/angular 中的行着色?
- linux - 无法从 git clone go.googlesource.com 克隆 Git 存储库
- python - openpyxl没有将数据框写入excel表
- latex - 改进 tikz 包中的输出
- c++ - LinkedListInit,LinkedListCreateH方法中的“L->next=NULL”有什么问题吗?
- kentico-kontent - 有没有办法使用 Kentico-Cloud 中的 ContentDelivery API 获取项目中定义的语言列表?
- google-cloud-build - 如何从 Google Cloud build github App 显示有关 github 检查的其他信息
- ruby-on-rails - Rails:是什么决定了传递的“参数”的名称?
- reactjs - 未处理的拒绝(TypeError):比较 id 时无法读取未定义的属性“”
- version - 如何从 CorDapp 代码访问 versionInfo?