Reputation: 438
Suppose I have:
const arr = [
{'name': 'P1','value': 150, 'nn': 2},
{'name': 'P1','value': 150, 'nn': 3},
{'name': 'P2','value': 200, 'nn': 5},
{'name': 'P3','value': 450, 'nn': 1}
]
const keysToSum = ['value', 'nn' ]
and I want:
[
{ name: 'P1', value: 300, nn: 5 },
{ name: 'P2', value: 200, nn: 5 },
{ name: 'P3', value: 450, nn: 1 }
]
So I want to sum the values inside the keys value
and nn
(because these keys are in keysToSum
) if name
is the same.
How can I do that?
I know I can use reduce
, for example:
const result = arr.reduce((acc, val) => {
const o = acc.filter((obj) => {
return obj.name == val.name;
}).pop() || {name: val.name, value: 0};
o.value += val.value;
acc.push(o);
return acc;
},[])
But this piece of code works with only a key
(value in that case), how can generalize it using keysToSum
?
const arr = [
{'name': 'P1','value': 150, 'nn': 2},
{'name': 'P1','value': 150, 'nn': 3},
{'name': 'P2','value': 200, 'nn': 5},
{'name': 'P3','value': 450, 'nn': 1}
];
const result = arr.reduce((acc, val) => {
const o = acc.filter((obj) => {
return obj.name == val.name;
}).pop() || {name: val.name, value: 0};
o.value += val.value;
acc.push(o);
return acc;
},[]);
console.log(result)
Upvotes: 0
Views: 91
Reputation: 207557
Using reduce with an object that uses the name as a key, you can easily keep track of the objecs with dupe and increment the properties.
const arr = [
{'name': 'P1','value': 150, 'nn': 0},
{'name': 'P1','value': 150, 'nn': 3},
{'name': 'P2','value': 200, 'nn': 2},
{'name': 'P3','value': 450, 'nn': 5}
]
const keysToSum = ['value', 'nn' ]
const summed = Object.values(arr.reduce((obj, record) => {
// have we seen this name yet? If not copy the record
if (!obj[record.name]) {
obj[record.name] = { ...record };
} else {
// if we saw it, sum the fields we care about
keysToSum.forEach(key => {
obj[record.name][key] += record[key];
})
}
return obj
}, {}));
console.log(summed)
Upvotes: 1
Reputation: 386868
You could reduce the array by using an object and iterate the wanted keys for summing property values.
const
array = [{ name: 'P1', value: 150, nn: 0 }, { name: 'P1', value: 150, nn: 3 }, { name: 'P2', value: 200, nn: 2 }, { name: 'P3', value: 450, nn: 5 }],
keysToSum = ['value', 'nn'],
result = Object.values(array.reduce((r, { name, ...o }) => {
if (!r[name]) r[name] = { name };
keysToSum.forEach(k => r[name][k] = (r[name][k] || 0) + o[k]);
return r;
}, []));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1