If I had data that looked like this:
harvest = [{type: "apple", color: "green", value: 1}, {type: "apple", color: "red", value: 2}, {type: "grape", color: "green", value: 3}, {type: "grape", color: "red", value: 4 }]
I could sum it over various attributes using the d3 function nest.rollup ():
sum_by = "color"; rollup = d3.nest().key(function(d) { return d[sum_by]; }).rollup(function(d) { return d3.sum(d, function(g) { return g.value; }); }).entries(harvest);
Give me that:
rollup = [{key: "green", values: 4}, {key: "red", values: 6}]
Which is exactly what I want.
However, the values ββin my data consist of arrays of the same length:
harvest = [{type: "apple", color: "green", values: [1,2,3,4]}, {type: "apple", color: "red", values: [5,6,7,8]}, {type: "grape", color: "green", values: [9,10,11,12]}, {type: "grape", color: "red", values: [13,14,15,16] }]
Is it possible to combine them in a similar way? For example:
rollup = [{key: "green", values: [10,12,14,16]}, {key: "red", values: [18,20,22,24]}]
I feel this is possible using the d3 accumulation function (but this does not have to be done using d3).
RESOLUTION
Thanks to the efforts of @meetamit and @Superboggly, I have three solutions:
Version 1 (preferable because it uses reduce() only once and map() only once):
function sumArrays(group) { return group.reduce(function(prev, cur, index, arr) { return { values: prev.values.map(function(d, i) { return d + cur.values[i]; }) }; }); }
Version 2:
function sumArrays(group) { return group.map(function(h) { return h.values; }).reduce(function(prev, cur, index, arr) { return prev.map(function(d, i) { return d + cur[i]; }); }); }
Version 3 (for fun, because the length of the array can vary):
function sumArrays(group) { return group.reduce(function(prev, cur, index, arr) { return prev.map(function(d, i) { return d + cur.values[i]; }); }, [0, 0, 0, 0]); }
Called like this:
function rollupArrays() { return d3.nest().key(function(d) { return d[sum_by]; }).rollup(sumArrays).entries(harvest); }
And converted to CoffeeScript:
rollupArrays = -> d3.nest().key (d) -> d[sum_by] .rollup(sumArrays).entries(harvest) sumArrays = (group) -> group.reduce (prev, cur, index, arr) -> values: prev.values.map (d,i) -> d + cur.values[i]
UPDATE
This method is not suitable if the function should be executed, even with a single line of input. See Part II