user2821789
user2821789

Reputation: 11

Algorithm Optimisation in Node, Javascript

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

Answers (1)

Ori Drori
Ori Drori

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

Related Questions