0

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.

1
  • The flaw in your logic is here: result[key] = []; you reset it every time. Idea is right. Commented Aug 23, 2019 at 16:49

5 Answers 5

1

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; }

Sign up to request clarification or add additional context in comments.

Comments

1

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);

Comments

0

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}

1 Comment

EXPLAIN what you did.
0

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);

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.