繁体   English   中英

如何对具有不同哈希值的数组中的值求和

[英]How to sum values in an array with different hash

我想对数组中相同项目的总值求和。

我有一个数组

[{"a"=>1},{"b"=>2},{"c"=>3},{"a"=>2},{"b"=>4}]

我想得到的结果

[{"a"=>3},{"b"=>6},{"c"=>3}]

哪种方法可以做到?

如果:

array = [{"a"=>1},{"b"=>2},{"c"=>3},{"a"=>2},{"b"=>4}]

那么您可以执行以下操作:

array.inject(Hash.new{|h,k| h[k] = 0})
      { |h, a| k, v = a.flatten;  h[k] += v; h }.
      map{|arr| Hash[*arr] }
#=> [{"a"=>3}, {"b"=>6}, {"c"=>3}]

要么:

array.each_with_object(Hash.new{|h,k| h[k] = 0})
      { |a, h| k, v = a.flatten;  h[k] += v }.
      map{|arr| Hash[*arr] }
#=> [{"a"=>3}, {"b"=>6}, {"c"=>3}]

可以如下进行

array.group_by { |h| h.keys.first }.
values.
map {|x| x.reduce({}) { |h1, h2| h1.merge(h2) { |_, o, n| o + n } }

#=> [{"a"=>3}, {"b"=>6}, {"c"=>3}]

有很多方法可以做到这一点。 看到一些,甚至是一些可能不正常和/或效率不高的指令是很有启发性的。

这是另一种方式:

arr = [{"a"=>1},{"b"=>2},{"c"=>3},{"a"=>2},{"b"=>4}]

arr.flat_map(&:keys)
   .uniq
   .map { |k| { k=>arr.reduce(0) { |t,g| t + (g.key?(k) ? g[k] : 0) } } } 
  #=> [{"a"=>3}, {"b"=>6}, {"c"=>3}]

由于nil.to_i => 0 ,我们可以改为将reduce的块编写为:

   { |t,g| t+g[k].to_i }

每次您要以非一对一的方式转换集合时, #reduce工作。 对于一对一转换,我们使用#map

array.reduce({}) { |h, acc| acc.merge(h) {|_k, o, n| o+n } }.zip.map(&:to_h)
# => [{"b"=>6}, {"a"=>3}, {"c"=>3}]

在这里,我们将reduce用作初始值{} ,并将其作为acc参数传递给块,然后使用带有手动“冲突解决”功能的#merge 这意味着仅当我们尝试合并的键已在方法接收器acc已经存在时才调用该块。 之后,我们将散列分解为散列数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM