Skip to content

Instantly share code, notes, and snippets.

@jsmithdev
Created October 24, 2024 13:03

Revisions

  1. jsmithdev created this gist Oct 24, 2024.
    79 changes: 79 additions & 0 deletions ExampleRecursiveSortSum.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@

    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 + ' - ');
    }
    }