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)