Reputation: 85
I am trying to compute multiple sums from an array of objects:
[{value1: 3, value2:6}, {value1: 2, value2: 4},...]
.
Potentially, the object can contain an unspecified number of keys (i.e. value1:, value2:, value3:..., value n).
Based on this example, the sum of all the value1 keys should return 5 while the sum of all the value2 keys should return 10.
What I did so far is as follows:
let sum = 0;
const myArrayObject = [{value1: 3, value2:6}, {value1: 2, value2: 4}];
const objectKeys = Object.keys(myArrayObject[0]); //Gives me the keys of the object
objectKeys.forEach(key => {
myArrayObject.map((entry) => {
sum += entry[key];
});
});
return sum;
This however gives me the total 15. Is there a way to actually compute the sum for all the value1 keys and value2 keys separately?
Upvotes: 0
Views: 1651
Reputation: 9370
Classic case for Array.prototype.reduce()
:
const data = [
{ value1: 3, value2: 6 },
{ value1: 2, value2: 4 },
];
const result = data.reduce((acc, curr) => {
Object.entries(curr).forEach((e) => (acc[e[0]] += e[1]));
return acc;
});
console.log(result);
Upvotes: 0
Reputation: 386868
By having same keys, you could reduce the array and create a new object with sums.
const
objects = [{ value1: 3, value2: 6 }, { value1: 2, value2: 4 }],
result = objects.reduce((a, b) => Object.fromEntries(Object
.entries(a)
.map(([k, v]) => [k, v + b[k]])
));
console.log(result);
Approach for different keys.
const
objects = [{ value0: 42, value1: 3, value2: 6 }, { value1: 2, value2: 4, value3: -42 }],
result = objects.reduce((r, o) => Object
.entries(o)
.reduce((t, [k, v]) => (t[k] = (t[k] || 0) + v, t), r),
{});
console.log(result);
Upvotes: 0
Reputation: 44275
If we use an extra object to 'group' those keys, we can later use that object to show the result:
const myArray = [{value1: 3, value2:6}, {value1: 2, value2: 4}];
let res = {};
for (let i = 0; i < myArray.length; i++) {
for (const [key, value] of Object.entries(myArray[i])) {
if (!res[key]) {
res[key] = 0;
}
res[key] += value;
}
}
for (const [key, value] of Object.entries(res)) {
console.log(`${key} has the sum of ${value}`);
}
Upvotes: 0
Reputation: 12894
const myArrayObject = [{value1: 3, value2:6}, {value1: 2, value2: 4}];
const result = myArrayObject.reduce((accum, current) => {
Object.entries(current).forEach(([key, value]) => {
accum[key] = (accum[key] + value) || value;
})
return {
...accum
}
}, {});
console.log(result)
Not as elegant as others but you may take a look, basically for each and every element, loop thru the entries
and add it to a temporarily variable during reduce
function
Upvotes: 1
Reputation: 5376
Example using an array myArraySum
for store the sum results:
let sum = 0;
let myArraySum = [];
const myArrayObject = [{value1: 3, value2:6}, {value1: 2, value2: 4}];
const objectKeys = Object.keys(myArrayObject[0]);
objectKeys.forEach(key => {
sum = 0;
myArrayObject.map((entry) => {
sum += entry[key];
});
myArraySum.push(sum);
});
console.log(myArraySum);
Upvotes: 0
Reputation: 78908
Here's a simple reduce-based solution:
const values = [
{ value1: 3, value2: 6 },
{ value1: 2, value2: 4 },
];
const basket = values.reduce((basket, value) => {
for (const [key, count] of Object.entries(value)) {
if (!basket[key]) {
basket[key] = 0;
}
basket[key] += count;
}
return basket;
}, {});
console.log(basket); // { value1: 5, value2: 10 }
Upvotes: 1