如何使用可枚举函数在二维数组中添加每组总和?

How do I add sums per group in two-dimensional array using enumerable functions?

我有一个二维数组如下:

ary = [["a", 10],["a", 20],["b", 9],["b",7],["c",12]]

我想用同一个键对数值求和,构建一个散列,如:

desired_result = {"a"=>30, "b"=>16, "c"=>12}

我可以使用具有默认值 (0) 和循环的散列,如下所示:

rslt = Hash.new(0)
ary.each do |line|
  rslt[line[0]] += line[1]
end

但我想避免循环并使用枚举函数。我想出了以下(非常丑陋)的表达方式:

rslt = ary.group_by {|a| a[0]}.map {|k,v| [k, v.map {|v| v[1]}.reduce(:+)]}.to_h

这比循环版本更难阅读。

有没有一种不用循环更优雅地做到这一点的方法?

ary = [["a", 10],["a", 20],["b", 9],["b",7],["c",12]]

h=ary.group_by{|x|x[0]}.each_with_object({}) do |(k,v),h|
  h[k]=v.sum{|y|y[1]}
end

p h

{"a"=>30, "b"=>16, "c"=>12}

您可以使用 each_with_object(或 inject)并传入一个散列,其中新键被初始化为零值:

ary.each_with_object(Hash.new(0)){ |(k, v), count| count[k] += v }
# => {"a"=>30, "b"=>16, "c"=>12}
ary.group_by(&:first).map {|k, v| [k, v.sum(&:last)]}.to_h

Enumerable#group_by I'd suggest to chain Hash#transform_values之后:

ary.group_by(&:first).transform_values { |v| v.sum(&:last) }
#=> {"a"=>30, "b"=>16, "c"=>12}