Andrew Hickman
Andrew Hickman

Reputation: 3

Adding object values based on matching keys

I have an array of objects and I'm trying to combine like keys and add the values. So X should be 0, Y should be 1, and B should be 3. Thanks for any help!!!!

const arr = [{X: -1}, {Y: 1}, {X: -4}, {B: 3}, {X: 5}];

let result = {};
for (let i = 0; i < arr.length; i++) {
    var item = arr[i];
    for (var key in item) {
        if (!(key in result))
            parseInt(item);
            result[key] = [];
            result[key] += item[key];
    }
}

console.log(result);

I expected X to be 0 but instead it is returning 5.

Upvotes: 0

Views: 692

Answers (5)

Christian Carrillo
Christian Carrillo

Reputation: 2761

a bit later but:

const arr = [{X: -1}, {Y: 1}, {X: -4}, {B: 3}, {X: 5}];

const result = arr.reduce((acc, item) =>{
  let currentKey = Object.keys(item)[0]
  return acc[currentKey] ? acc[currentKey] += item[currentKey] : acc[currentKey] = item[currentKey], acc
}, {})

console.log(result)

Upvotes: 0

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48600

You can reduce each item (object) by grabbing the key and assigning the added previous value with the current value.

const input = [ {X: -1}, {Y: 1}, {X: -4}, {B: 3}, {X: 5} ];

let response = input.reduce((obj, item) => {
  return ((key) => Object.assign(obj, {
    [key] : (obj[key] || 0) + item[key] // Add previous with current
  }))(Object.keys(item)[0]);
});

console.log(response);
.as-console-wrapper { top: 0; max-height: 100% !important; }

Result

{
  "X": 0,
  "Y": 1,
  "B": 3
}

Fun Code Golf Experiment

I changed Object.assign(o,{[k]:(o[k]||0)+e[k]}) to ({...o,[k]:(o[k]||0)+e[k]}) by utilizing the spread operator to save 10 bytes.

r=i=>i.reduce((o,e) =>(k=>({...o,[k]:(o[k]||0)+e[k]}))(Object.keys(e)[0])) // 74 bytes
console.log(r([{X:-1},{Y:1},{X:-4},{B:3},{X:5}]))
.as-console-wrapper { top: 0; max-height: 100% !important; }

Upvotes: 1

Tom O.
Tom O.

Reputation: 5941

You could use Array.prototype.reduce with Object.entries to group by key in order to summate the values.

Example below (check the comments for more details):

const arr = [{
  X: -1
}, {
  Y: 1
}, {
  X: -4
}, {
  B: 3
}, {
  X: 5
}];

//Iterate the object els in the arr
const map = arr.reduce((accum, el) => {
  //Destructure the object into some clearly defined variables
  const [
    [key, value]
  ] = Object.entries(el);
  //Check the key against the map
  if (accum[key] != null) {
    //Add the value to the existing map value
    accum[key] += value;
  } else {
    //Set the initial value in the map
    accum[key] = value;
  }
  return accum;
}, {});

console.log(map);

Upvotes: 1

Ivan86
Ivan86

Reputation: 5708

Simple solution:

const arr = [{X: -1}, {Y: 1}, {X: -4}, {B: 3}, {X: 5}];

let result = {};
for (let i = 0; i < arr.length; i++) {
    var item = arr[i];
    for (var key in item) {
        if (result[key]) {  // if key exists
            result[key] += parseInt(item[key]);
        } else {            // if key doesn't exist
            result[key] = parseInt(item[key]);
        }
    }
}

console.log(result);

Upvotes: 0

ferhatelmas
ferhatelmas

Reputation: 3978

Here is inner loop changed such that we access the key, if exists, it's used; otherwise it's initialized to zero. Then value is added.

const arr = [{X: -1}, {Y: 1}, {X: -4}, {B: 3}, {X: 5}];

let result = {};
for (let i = 0; i < arr.length; i++) {
    var item = arr[i];
    for (var key in item) {
        result[key] = (result[key] || 0) + item[key] // changed here
    }
}

console.log(result);
{X: 0, Y: 1, B: 3}

Upvotes: 0

Related Questions