我有以下定义的表格。每行中每个元素的索引对应于同一个字段。
[[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]]
最好的方法是什么?
答案 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作为键的哈希作为数据结构更有意义。