如何在唯一键上对嵌套数组的多个元素求和

时间:2016-05-26 05:55:34

标签: arrays ruby

我有以下定义的表格。每行中每个元素的索引对应于同一个字段。

[[123.0, 23,"id1",34, "abc"], 
 [234.1,43, "id2", 24,"jsk"],
 [423.5,53, "id1",1,"xyz"],
 [1.4, 5, "id2",0,"klm"]]

在上面的例子中,我需要对输出进行分组和求和,该输出对第3列中唯一标识符的索引上的每个可求元素求和。结果应如下所示:

[[546.5,76, "id1",35],
 [235.5,48, "id2",24]]

最好的方法是什么?

1 个答案:

答案 0 :(得分:1)

这与previous question的解决方案基本相同。

data = [ [ 123.0, 23, "id1", 34, "abc" ], 
         [ 234.1, 43, "id2", 24, "jsk" ],
         [ 423.5, 53, "id1",  1, "xyz" ],
         [   1.4,  5, "id2",  0, "klm" ] ]

sums = Hash.new {|h,k| h[k] = [0, 0, 0] }

data.each_with_object(sums) do |(val0, val1, id, val2, _), sums|
  sums[id][0] += val0
  sums[id][1] += val1
  sums[id][2] += val2
end
# => { "id1" => [ 546.5, 76, 35 ],
#      "id2" => [ 235.5, 48, 24 ] }

主要区别在于,我们不是给Hash一个默认值0,而是给它一个默认的proc,用[0, 0, 0]初始化缺少的键。 (我们不能只做Hash.new([0, 0, 0]),因为那时每个值都是对单个Array实例的引用,而不是每个值都有自己的Array。)然后,在块内部,我们添加每个值({{1 }} et al)到val0的相应元素。

如果你想要一个数组数组而不是索引为2的sums[id]的哈希,那么最后你需要添加如下内容:

id

但是,使用id作为键的哈希作为数据结构更有意义。