skip to Main Content

Input

let categories =[
{id:1, name:'Electronics', parentId:''},
{id:2, name:'Devices', parentId:1},
{id:3, name:'Mobile Phones', parentId:2},
{id:4, name:'TV', parentId:2},
{id:5, name:'Accessories', parentId:1},
{id:6, name:'Beauty', parentId:''},
]

Expected Output

let categories =[
 {id:1, name:'Electronics', parentId:'', subCategories:[
   {id:2, name:'Devices', parentId:1, subCategories:[
     {id:3, name:'Mobile Phones', parentId:2},
     {id:4, name:'TV', parentId:2}}
    ]
   },
   {id:5, name:'Accessories', parentId:1}
  ]
 },
 {id:6, name:'Beauty',parentId:''}
]

Explanation

So above in Input array

id:1 and id:6 has no parentId. That means they are the root categories in Expected Output.

id:2 and id:5 has parentId:1. That means they are
subcategories of id:1 and goes into the subCategories array of id:1.

id:3 and id:4 has parentId:2. That means they are subcategories of id:2 and goes into the subCategories array of id:2.

and there could be more nested subCategories.

for example

A new object id:7 can have a parentId:4.So it is a subCategory of id:4 and goes into the subCategories array of id:4

2

Answers


  1. You could build a tree with all related pairs children/parent, parent/children and return the nodes with no parent '' as tree.

    const
        categories = [{ id: 1, name: 'Electronics', parentId: '' }, { id: 2, name: 'Devices', parentId: 1 }, { id: 3, name: 'Mobile Phones', parentId: 2 }, { id: 4, name: 'TV', parentId: 2 }, { id: 5, name: 'Accessories', parentId: 1 }, { id: 6, name: 'Beauty', parentId: '' }],
        tree = categories
            .reduce((t, o) => {
                Object.assign(t[o.id] = t[o.id] || {}, o);
                ((t[o.parentId] ??= {}).children ??= []).push(t[o.id]);
                return t;
            }, {})
            ['']
            .children;
    
    console.log(tree);
    .as-console-wrapper { max-height: 100% !important; top: 0; }
    Login or Signup to reply.
  2. You can use map to create helper catObj where key is the id and value is the item of categories. Next use forEach loop to conditionally push sub-categories or root-categories to the adequate array based on the existence of parentCat.

    let categories =[
      {id:1, name:'Electronics', parentId:''},
      {id:2, name:'Devices', parentId:1},
      {id:3, name:'Mobile Phones', parentId:2},
      {id:4, name:'TV', parentId:2},
      {id:5, name:'Accessories', parentId:1},
      {id:6, name:'Beauty', parentId:''},
    ];
    
    const makeTree = (cats) => {
    
      const catObj = {}, rootCats = [];
    
      cats.map((cat) => (catObj[cat.id] = { ...cat }))
      .forEach((cat) => {
        const parentCat = catObj[cat.parentId];
        if (parentCat) {
           parentCat.subCategories = parentCat.subCategories || [];
           parentCat.subCategories.push(cat);
         } else {
           rootCats.push(cat);
        }
      });
    
      return rootCats;
    }
    
    
    
    const catTree = makeTree(categories);
    console.log(catTree);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search