Home > Enterprise >  How to sum values with the same key In an array of objects?
How to sum values with the same key In an array of objects?

Time:04-20

Let's say I have an array of objects like so:

this.arrayOfObjects = [{
    {
        "grouppresentation": "11",
        "evaluation": null,
        "datacontext": null,
        "category": "Group Presentation"
    },
    {
        "grouppresentation": null,
        "evaluation": "23",
        "datacontext": null,
        "category": "Evaluation"
    },
    {
        "grouppresentation": null,
        "evaluation": "46",
        "datacontext": null,
        "category": "Evaluation"
    },
    {
        "grouppresentation": "44",
        "evaluation": null,
        "datacontext": null,
        "category": "Group Presentation"
    },
    {
        "grouppresentation": null,
        "evaluation": null,
        "datacontext": "21",
        "category": "Data Context"
    }
}]

The keys in each object is defined by the values in the "category" key. Meaning that if "category" = "Group Presentation", then there exists a key called "grouppresentation" where the "category" value has been converted using replace(' ', '').toLowerCase().

It is not shown above, but there's an object with "category" = "Data Context" and so there's a key in the same object called "datacontext".

Another important note is that if "category" = "Group Presentation", then the "grouppresentation" key will have a value i.e. a number. The other keys will be set to null, so the only keys with an actual value is "category" and "grouppresentation". Like so but with category "Evaluation":

    {
        "grouppresentation": null,
        "evaluation": "46",
        "datacontext": null,
        "category": "Evaluation"
    },

GOAL

I want for each item with the same 'category' value, to sum the values of the key that represents that value:

So,

this.newArrayOfObjects = [{
    {
        "grouppresentation": "55",     -> because 11   44 from the values above
        "evaluation": null,
        "datacontext": null,
        "category": "Group Presentation"
    },
    {
        "grouppresentation": null,
        "evaluation": "69",    -> because 46   23 from the values above
        "datacontext": null,
        "category": "Evaluation"
    },
    {
        "grouppresentation": null,
        "evaluation": null,
        "datacontext": "21",
        "category": "Data Context"
    }
}]

So far, I've attempted several methods, one of which being:

var newObject = {};

this.arrayOfObjects.forEach(function(item) {
  if (newObject.hasOwnProperty(item.category)) {
    newObject[item.name] = newObject[item.category.replace(' ', '').toLowerCase()]   item.category.replace(' ', '').toLowerCase();
  } else {
    newObject[item.name] = item.category.replace(' ', '').toLowerCase();
  }
});

However, it unfortunately does no get anywhere and yields the following:

{undefined: 'grouppresentation'}

Would you have any idea how achieve the above?

CodePudding user response:

Array#reduce is one way of getting there. Basically we just check each iteration for a match on the category. If there is match, we add the appropriate values together (converting both to numbers on the fly)

let arrayOfObjects = [{
    "grouppresentation": "11",
    "evaluation": null,
    "datacontext": null,
    "category": "Group Presentation"
  },
  {
    "grouppresentation": null,
    "evaluation": "23",
    "datacontext": null,
    "category": "Evaluation"
  },
  {
    "grouppresentation": null,
    "evaluation": "46",
    "datacontext": null,
    "category": "Evaluation"
  },
  {
    "grouppresentation": "44",
    "evaluation": null,
    "datacontext": null,
    "category": "Group Presentation"
  },
  {
    "grouppresentation": null,
    "evaluation": null,
    "datacontext": "21",
    "category": "Data Context"
  }
]

let newArrayOfObjects = arrayOfObjects.reduce((b, a) => {
  let ind = b.findIndex(e => e.category === a.category);
  let c = a.category.toLowerCase().split(' ').join('');
  if (ind > -1) {
    b[ind][c] =  b[ind][c]    a[c]
  } else {
    a[c] =  a[c] || 0
    b.push(a)
  }
  return b;
}, []);

console.log(newArrayOfObjects)

  • Related