ASO
ASO

Reputation: 85

Calculate multiple sum of an array of objects in Javascript

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

Answers (6)

Behemoth
Behemoth

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

Nina Scholz
Nina Scholz

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

0stone0
0stone0

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

Isaac
Isaac

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

ℛɑƒ&#230;Ŀᴿᴹᴿ
ℛɑƒ&#230;Ŀᴿᴹᴿ

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

jarmod
jarmod

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

Related Questions