Reputation: 11
Given the following json array
const groups=[{ id:1, parent:null, groupName:'Others', maxScore:3},
{id:2, parent:null, groupName: 'Group 1', maxScore:0},
{id:3, parent:2, groupName:'Others, maxScore:2},
{id:4, parent:2, groupName:'Sub Group 1', maxScore:1}];
What would be a more performance oriented approach to sum maxScores within parents ? It looks like a tree structure, but nodes don't have references to their children.
Im trying a map.reduce approach right now
function addMaxScoreToGroups(groups) {
return groups.map((group) => {
const newGroup = group;
if (group.parent === null && group.name !== 'Others') {
const children = groups.filter(elem => elem.parent === group.id);
if (children) {
newGroup.maxScore = children.map(x => x.maxScore)
.reduce((value, acum) => value + acum);
}
}
return newGroup;
});
}
Expected result would be
const groups=[{ id:1, parent:null, groupName:'Others', maxScore:3},
{id:2, parent:null, groupName: 'Group 1', maxScore:0,maxPosibleScore:3},
{id:3, parent:2, groupName:'Others, maxScore:2},
{id:4, parent:2, groupName:'Sub Group 1', maxScore:1}];
Upvotes: 0
Views: 71
Reputation: 191986
Iterate the with Array.reduce()
. For each object create a new entry (or update existing one in case of parent) by cloning the object using object spread (or Object.assign()
.
If the object has a parent, create the parent if it doesn't exist, and add/update the maxPossibleScore
.
Convert back to array using Object.values()
.
const groups=[{ id:1, parent:null, groupName:'Others', maxScore:3}, {id:3, parent:2, groupName:'Others', maxScore:2}, {id:4, parent:2, groupName:'Sub Group 1', maxScore:1}, {id:2, parent:null, groupName: 'Group 1', maxScore:5}];
const ms = 'maxScore';
const mps = 'maxPossibleScore';
const result = Object.values(groups.reduce((r, o) => {
// clone
const c = { ...o };
// if current parent initalized before, update maxPossibleScore
if(!o.parent && r[o.id]) c[mps] = r[o.id][mps] + c[ms];
r[o.id] = c;
if(o.parent) {
// if parent doesn't exist init
r[o.parent] = r[o.parent] || {};
// if parent.maxPossibleScore doesn't exist init it
if(!(mps in r[o.parent])) {
r[o.parent][mps] = r[o.parent][ms] || 0;
}
r[o.parent][mps] += o[ms];
}
return r;
}, {}));
console.log(result);
Upvotes: 1