Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在Ruby中合并哈希数组并计算相同的键_Ruby On Rails_Ruby - Fatal编程技术网

Ruby on rails 在Ruby中合并哈希数组并计算相同的键

Ruby on rails 在Ruby中合并哈希数组并计算相同的键,ruby-on-rails,ruby,Ruby On Rails,Ruby,我有一些这种格式的数据 [{ "_id" => "20", "value" => 1 }, { "_id" => "19", "value" => 1 }, { "_id" => nil, "value" => 8 }, { "_id" => "27", "value" => 1 }, { "_id" => "25", "value" => 3 }, {

我有一些这种格式的数据

[{
    "_id" => "20",
    "value" => 1
}, {
    "_id" => "19",
    "value" => 1
}, {
    "_id" => nil,
    "value" => 8
}, {
    "_id" => "27",
    "value" => 1
}, {
    "_id" => "25",
    "value" => 3
}, {
    "_id" => "28",
    "value" => 1
}]
我想用“_id”键合并相同的值,并对“value”值求和

期望输出

[{
    "_id" => "20",
    "value" => 1
}, {
    "_id" => "19",
    "value" => 2
}, {
    "_id" => nil,
    "value" => 8
}, ...]
有一种优雅的方法可以做到这一点吗


我尝试过两个循环,但我认为这不是最好的方法。

与Ruby中的大多数内容一样,浏览文档可以找到一种方法,它可以帮助根据一些任意标准将内容组合在一起。把它和求和的东西结合起来,你会得到:

v.group_by do |e|
  e['_id']
end.map do |id, list|
  {
    '_id' => id,
    'value' => list.inject(0) { |sum, e| sum + e['value'] }
  }
end

# => [{"_id"=>"20", "value"=>1}, {"_id"=>"19", "value"=>2}, {"_id"=>nil, "value"=>28},
#     {"_id"=>"27", "value"=>1}, {"_id"=>"25", "value"=>3}, {"_id"=>"28", "value"=>1},
#     {"_id"=>"23", "value"=>1}, {"_id"=>"16", "value"=>1}, {"_id"=>"18", "value"=>2},
#     {"_id"=>"22", "value"=>2}]
如果您想返回一个散列数组,其中包含
“\u id”
的唯一值以及更新的
“value”
的值,您可以首先计算上面的
h
,然后

arr.uniq { |g| g["_id"] }.map { |g| g.update("_id"=>h[g["_id"]]) }
  #=> [{"_id"=>"20", "value"=>2}, {"_id"=>" 19", "value"=>2},
  #    {"_id"=>nil, "value"=>8}, {"_id"=>"25", "value"=>3}]  
这将使用带块的方法和(也称为
merge!

或者,您可以编写以下内容

arr.each_with_object({}) { |g,h|
  h.update(g["_id"]=>g) { |_,o,n| o.merge("value"=>o["value"]+n["value"]) } }.values
  #=> [{"_id"=>"20", "value"=>2}, {"_id"=>" 19", "value"=>2},
  #    {"_id"=>nil, "value"=>8}, {"_id"=>"25", "value"=>3}]  

同样,我使用了
Hash#update
,但这次我使用了一个块来确定合并的两个哈希中存在的键的值。另见和。请注意,作为参数,
(k=>v)
({k=>v})
的缩写,请阅读“”、链接页面和“”。你试过什么?我们需要看到演示问题的最小代码,以及绝对最小输入数据。如果没有这些,看起来你想让我们做你的工作。“”也适用。您不需要更新“输出示例”吗?您可以称之为“预期输出”或“预期输出”。您的输出仍然与输入不匹配(
“\u id=>“19”
)。此外,请给出完整的预期输出(无
)。
arr.each_with_object({}) { |g,h|
  h.update(g["_id"]=>g) { |_,o,n| o.merge("value"=>o["value"]+n["value"]) } }.values
  #=> [{"_id"=>"20", "value"=>2}, {"_id"=>" 19", "value"=>2},
  #    {"_id"=>nil, "value"=>8}, {"_id"=>"25", "value"=>3}]