Home > Mobile >  How to get desired category tree with top parent having predefined value
How to get desired category tree with top parent having predefined value

Time:10-21

Hi i want to get children tree from a category list.

here is my input data

[
  { "parent_id": -1, "name": "Toothpaste", "id": 99 },
   {
        "parent_id": -1,
        "name": "Cake",
        "id": 3
    },
    {
        "parent_id": 3,
        "name": "Chocolate  Cake",
        "id": 4
    },
    {
        "parent_id": 3,
        "name": "Walnut Cake",
        "id": 5
    },
    {
        "parent_id": 4,
        "name": "Chocolate Cake mixin 1",
        "id": 6
    }
]

my desired output will look like below one

[ { "parent_id": -1, "name": "Toothpaste", "id": 99 },
   {
    "parent_id": -1,
    "name": "Cake",
    "id": 3,
    "children":[
        {
            "parent_id": 3,
            "name": "Chocolate  Cake",
            "id": 4,
            "children":[     //<--- observe this one not there in my output 
                {
                    "parent_id": 4,
                    "name": "Chocolate Cake mixin 1",
                    "id": 6
                }
            ]
        },
        {
            "parent_id": 3,
            "name": "Walnut Cake",
            "id": 5
        }
    ],
  }

]

The problem i'm facing is that i'm unable to push data into 2nd level i,e chocolate cake is having children but i'm unable to push that into chocolate cake children

Note: solution must work for any level of nesting

here is what i have tried

function getChildrenTree(childList){
        let childMap = {};
        for(let i = 0; i < childList.length; i  ){
           if(childList[i].parent_id === -1)
              childMap[childList[i].id] = {name:childList[i].name,children:[]};
          
        }
    
        for(let i = 0; i < childList.length; i  ){
            if(childMap && childMap.hasOwnProperty(childList[i].parent_id) && childMap[childList[i].parent_id].hasOwnProperty('children')) childMap[childList[i].parent_id].children.push(childList[i]);
        }
         
       return Object.values(childMap);
    }

getChildrenTree([ { "parent_id": -1, "name": "Toothpaste", "id": 99 },{ "parent_id": -1, "name": "Cake", "id": 3 }, { "parent_id": 3, "name": "Chocolate  Cake", "id": 4 }, { "parent_id": 3, "name": "Walnut Cake", "id": 5 }, { "parent_id": 4, "name": "Chocolate Cake mixin 1", "id": 6 } ])
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Here's an approach you can try.

const flat = [
  { "parent_id": -1, "name": "Toothpaste", "id": 99 },
   {
        "parent_id": -1,
        "name": "Cake",
        "id": 3
    },
    {
        "parent_id": 3,
        "name": "Chocolate  Cake",
        "id": 4
    },
    {
        "parent_id": 3,
        "name": "Walnut Cake",
        "id": 5
    },
    {
        "parent_id": 4,
        "name": "Chocolate Cake mixin 1",
        "id": 6
    }
];

const makeTree = (arr, parent) => {
  const branch = arr.filter(node => node.parent_id === parent);
  branch.forEach(node => {
    const children = makeTree(arr, node.id);
    if (children.length) {
      node.children = children;
    }
  });
  return branch;
};

const tree = makeTree(flat, -1);

console.log(tree);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You could take a single loop and and object for collecting the nodes and return a tree by taking all children from the root node.

const
    buildTree = (data, root) => {
        var t = {};
        data.forEach(o => {
            Object.assign(t[o.id] = t[o.id] || {}, { ...o });
            ((t[o.parent_id] ??= {}).children ??= []).push(t[o.id]);
        });
        return t[root].children
    },
    data = [{ parent_id: -1, name: "Toothpaste", id: 99 }, { parent_id: -1, name: "Cake", id: 3 }, { parent_id: 3, name: "Chocolate  Cake", id: 4 }, { parent_id: 3, name: "Walnut Cake", id: 5 }, { parent_id: 4, name: "Chocolate Cake mixin 1", id: 6 }],
    tree = buildTree(data, -1);


console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related