This is essentially the same as the solution to your 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 ] }
The main difference is that instead of giving the Hash a default value of 0
, we’re giving it a default proc that initializes missing keys with [0, 0, 0]
. (We can’t just do Hash.new([0, 0, 0])
because then every value would be a reference to a single Array instance, rather than each value having its own Array.) Then, inside the block, we add each value (val0
et al) to the corresponding elements of sums[id]
.
If you wanted an Array of Arrays instead of a Hash with the id
at index 2, then at the end, you would have to add something like this:
.map {|id, vals| vals.insert(2, id) }
However, a Hash with the ids as keys makes more sense as a data structure.
3
solved How to sum multiple elements of nested arrays on unique keys [duplicate]