JavaScript array sorting by level


We have data with a one to many relationships in the same array. The organization is established by level. An element's parent is always one level higher than itself and is referenced by parentId.

We are required to get a multi-level array from this array. The elements with the highest level would be the main array, with their children as subarray.

If the input array is given by −

const arr = [
   {
      _id: 100,
      level: 3,
      parentId: null,
   },
   {
      _id: 101,
      level: 2,
      parentId: 100,
   },
   {
      _id: 102,
      level: 2,
      parentId: 100,
   },
   {
      _id: 103,
      level: 2,
      parentId: 100,
   },
   {
      _id: 104,
      level: 1,
      parentId: 101,
   },
   {
      _id: 105,
      level: 1,
      parentId: 102,
   },
   {
      _id: 106,
      level: 1,
      parentId: 101,
   },
   {
      _id: 107,
      level: 1,
      parentId: 103,
   },
   {
      _id: 108,
      level: 1,
      parentId: 102,
   },
   {
      _id: 109,
      level: 1,
      parentId: 103,
   }
];

Then the output structure should be something like −

                                          100
                                           |
                           ------------------------------------
                           |                |                  |
                          101              102                103
                        -------          ------              ------
                        |     |          |    |              |    |
                       104   106        105  108            107   109

Example

The code for this will be −

const arr = [{
   _id: 100,
   level: 3,
   parentId: null,
},
{
   _id: 101,
   level: 2,
   parentId: 100,
},
{
   _id: 102,
   level: 2,
   parentId: 100,
},
{
   _id: 103,
   level: 2,
   parentId: 100,
},
{
   _id: 104,
   level: 1,
   parentId: 101,
},
{
   _id: 105,
   level: 1,
   parentId: 102,
},
{
   _id: 106,
   level: 1,
   parentId: 101,
},
{
   _id: 107,
   level: 1,
   parentId: 103,
},
{
   _id: 108,
   level: 1,
   parentId: 102,
},
{
   _id: 109,
   level: 1,
   parentId: 103,
}];
const prepareTree = (arr = [], root = null) => {
   let res;
   const obj = Object.create(null);
   arr.forEach(el => {
      el.children = obj[el._id] && obj[el._id].children;
      obj[el._id] = el;
      if (el.parentId === root) {
         res = el;
      }
      else {
         obj[el.parentId] = obj[el.parentId] || {};
         obj[el.parentId].children = obj[el.parentId].children || [];
         obj[el.parentId].children.push(el);
      }
   });
return res;
};
console.log(JSON.stringify(prepareTree(arr), undefined, 4));

Output

And the output in the console will be −

{
   "_id": 100,
   "level": 3,
   "parentId": null,
   "children": [
      {
         "_id": 101,
         "level": 2,
         "parentId": 100,
         "children": [
            {
               "_id": 104,
               "level": 1,
               "parentId": 101
            },
            {
               "_id": 106,
               "level": 1,
               "parentId": 101
            }
         ]
      },
      {
         "_id": 102,
         "level": 2,
         "parentId": 100,
         "children": [
            {
               "_id": 105,
               "level": 1,
               "parentId": 102
            },
            {
               "_id": 108,
               "level": 1,
               "parentId": 102
            }
         ]
      },
      {
         "_id": 103,
         "level": 2,
         "parentId": 100,
         "children": [
            {
               "_id": 107,
               "level": 1,
               "parentId": 103
            },
            {
               "_id": 109,
               "level": 1,
               "parentId": 103
            }
         ]
      }
   ]
}

Updated on: 24-Nov-2020

681 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements