I have an array like the following:
[
{"sku": 123, "val": 10},
{"sku": 124, "val":12},
{"sku": 123, "val": 20}
]
Is there a quick way in javascript to sum val
of objects with the same sku property, so the result would be:
[
{"sku": 123, "val": 30},
{"sku": 124, "val":12}
]
You should group the entries by their SKU and then map the entries to an SKU and the reduced (sum of) values.
const data = [
{ "sku": 123, "val": 10 },
{ "sku": 124, "val": 12 },
{ "sku": 123, "val": 20 }
];
const groupBy = (arr, key) => arr.reduce((acc, entry) => ({
...acc, [entry[key]]: [ ...(acc[entry[key]] || []), entry ]
}), {});
const sum = Object.entries(groupBy(data, 'sku'))
.map(([key, values]) =>
({
'sku': key,
'val': values.reduce((acc, { val }) => acc + val, 0)
}))
console.log(sum);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Here is a more dynamic version that allows for multiple reducers with various aggregation techniques.
const groupBy = (arr, key) => arr.reduce((acc, entry) => ({
...acc, [entry[key]]: [ ...(acc[entry[key]] || []), entry ]
}), {});
const aggregate = (arr, key, reducers) =>
Object.entries(groupBy(arr, key))
.map(([k1, values]) => Object.entries(reducers)
.reduce((obj, [k2, { fn, initial }]) => ({
...obj,
[k2]: values.reduce((acc, item, index, all) =>
fn(acc, item[k2], index, all), initial || 0)
}), { [key]: k1 }))
const data = [
{ "sku": 123, "val": 10, "val2": 2 },
{ "sku": 124, "val": 12, "val2": 5 },
{ "sku": 123, "val": 20, "val2": 8 }
];
const aggregated = aggregate(data, 'sku', {
'val' : { fn: (acc, val) => acc + val, initial: 0 },
'val2' : { fn: (acc, val) => acc * val, initial: 1 }
});
console.log(aggregated);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments