Skip to content

Instantly share code, notes, and snippets.

@jsmithdev
Created October 24, 2024 13:03
Show Gist options
  • Save jsmithdev/3aa7a38544412fe65747b0384b9ae8d4 to your computer and use it in GitHub Desktop.
Save jsmithdev/3aa7a38544412fe65747b0384b9ae8d4 to your computer and use it in GitHub Desktop.
An example of recursively sorting then summing chained data structures
const data = [
{ Id: 'a0wcn0000006DxTEST0', SBQQ__RequiredBy__c: '', SBQQ__PartnerTotal__c: 0, Children_Total__c: 0, },
{ Id: 'a0wcn0000006DxTEST1', SBQQ__RequiredBy__c: 'a0wcn0000006DxTEST0', SBQQ__PartnerTotal__c: 1, Children_Total__c: 0, },
{ Id: 'a0wcn0000006DxTEST4', SBQQ__RequiredBy__c: 'a0wcn0000006DxTEST3', SBQQ__PartnerTotal__c: 1, Children_Total__c: 0, },
{ Id: 'a0wcn0000006DxTEST2', SBQQ__RequiredBy__c: 'a0wcn0000006DxTEST1', SBQQ__PartnerTotal__c: 1, Children_Total__c: 0, },
{ Id: 'a0wcn0000006DxTEST3', SBQQ__RequiredBy__c: 'a0wcn0000006DxTEST2', SBQQ__PartnerTotal__c: 1, Children_Total__c: 0, },
]
/* Start sort */
// function to check if the item is top level
const isTopLevel = (item) => !item.SBQQ__RequiredBy__c;
// function to recursively add children to parent
function recursivelyAddToParent(parents, item, found = false) {
for (const parent of parents) {
if (parent.Id === item.SBQQ__RequiredBy__c) {
parent.children = parent.children || [];
found = true;
parent.children.push(item);
} else {
if(!parent.children) parent.children = [];
const result = recursivelyAddToParent(parent.children, item, found);
found = result.found;
}
}
return { parents, found };
}
// separate top level and sub level items
const roots = data.filter(isTopLevel);
const subs = data.filter(item => !isTopLevel(item));
let stage = [...roots]
for(let i = 0; i < subs.length; i++) {
const item = subs[i];
item.children = item.children || [];
const { parents, found } = recursivelyAddToParent(stage, item);
if (!found) {
subs[subs.length] = item;
}
else if(parents) {
stage = parents;
}
}
/* Start sum */
const sumChildren = (parent, isRoot) => {
const startValue = isRoot ? parent.Children_Total__c : parent.SBQQ__PartnerTotal__c;
return parent.children.reduce((acc, child) => acc + sumChildren(child, false), startValue);
}
function recursivelySumChildren(parents) {
for(const parent of parents) {
parent.Children_Total__c = sumChildren(parent, true);
recursivelySumChildren(parent.children);
}
}
recursivelySumChildren(stage);
/* Start log */
// below is just for logging
recursivelyLogChildren(stage);
function recursivelyLogChildren(parents, dash = '') {
for(const parent of parents) {
console.log(dash+' '+parent.Id +' = ' + parent.Children_Total__c);
recursivelyLogChildren(parent.children, dash + ' - ');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment