问题
I recently posted this question about summing arrays in JavaScript using d3.nest()
I got a good solution (two in fact), but it turns out both have an issue when adapted to append additional information:
data = [
{
continent: 'africa',
country: 'gabon',
values: [1, 2]
}, {
continent: 'africa',
country: 'chad',
values: [3, 4]
}, {
continent: 'asia',
country: 'china',
values: [1, 2]
}
];
sum_by = 'continent';
rollupAgg = function(data, sum_by) {
return d3.nest().key(function(d) {
return d[sum_by];
}).rollup(function(group) {
return group.reduce(function(prev, cur, index, arr) {
return {
values: prev.values.map(function(d, i) {
return d + cur.values[i];
}),
sum_by: sum_by // additional information
};
});
}).entries(data);
};
reduce() doesn't run if there is only one row in that group, so this returns the following:
[
{
"key": "africa",
"values": {
"values": [4, 6],
"sum_by": "continent"
}
}, {
"key": "asia",
"values": {
"continent": "asia",
"country": "china", // country information shouldn't have been retained
"values": [1, 2]
} // sum_by information should have been added
}
];
Can you see a way to modify this function so that it returns the desired result?
回答1:
Hasn't occurred to me till now that a single element array will not execute the function; but it makes sense, because you're using with a single param:
[].reduce(function(prev, curr, i, arr) {});// <-- function is the only param
When used with a single param, the behavior is that the first time the function is executed, i equals 1 (not 0), and prev and curr are the first and second elements of the array. Since you only have one element, there's no way to call it in this form.
If you use reduce with a 2nd param:
[].reduce(function(prev, curr, i, arr) {}, { foo:'bar' });// <-- 2nd param {foo:bar}
it does actually call the function, with the first call passing i equal to 0 and prev equaling { foo:'bar' }.
So I guess you have 2 options:
Either modify it to pass a 2nd param, which in your case would need to be
{ values:[0,0] }(and that hardcodes the fact thatvaluesis always 2 elements, which will cause an issue if it's longer).Check if
group.length == 1and if so,return group, instead of calling reduce.
来源:https://stackoverflow.com/questions/13713784/summing-arrays-in-javascript-using-d3-nest-part-ii