Summing a 2D array by "group"
Use reduce()
to sum and map()
to change it to the format you want.
var vals = [
['16-24', 192081],
['16-24', 94452],
['16-24', 1055],
['25-34', 192081],
['25-34', 94452],
['25-34', 1055]
];
var temp = vals.reduce(function (obj, cur) {
var total = obj[cur[0]] || 0;
obj[cur[0]] = total + cur[1];
return obj;
}, {} );
var result = Object.keys(temp).map( function (key) { return [key, temp[key]]; });
console.log(result);
Here is an approach which calculates the sums "in-place", avoiding the necessity of having to create a separate object with reduce etc., then converting the object back into an array.
The basic plan is to add to the first occurrence of each key the numbers from subsequent occurrences, then filter out those subsequent occurrences.
function sum(a) {
return a.filter(([key, num], idx) => {
var first = a.findIndex(([key2]) => key === key2);
if (first === idx) return true;
a[first][1] += num;
});
}
For each tuple, we use findIndex
to find the first tuple with the same key. By comparing that index with the current index, we can tell if the current tuple is the first occurrence. If it is, we leave it alone (return true;
); otherwise, we filter it out, but first add its value to the first occurrence. This avoids the necessity of having to create an object with reduce
etc., then converting the object back into an array.
The possibly unfamiliar syntax ([key, num], idx)
is function parameter destructuring. It takes the first parameter, assumes it's an array, and assigns the first element to key
and the second element to num
. This is a bit cleaner than referring to a[0]
and a[1]
from within the code.