David Nathanael David Nathanael - 2 days ago 5
Javascript Question

Javascript array sorting by level

I have data with a one to many relationship 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.

How would you get a multi level array from this array? The elements with the highest level would be the main array, with their children as subarray in javascript?

[{
_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,
}]


Expected output would be

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


Thanks

Answer

Create a hash by id of the the nodes using Array#reduce, then iterate the array with Array.forEach(). If the parent id is null, it's the root, if not add it to the parent's children:

function createTree(data) {
  var tree = [];
  
  data.forEach(function(node) {
    var parentId = node.parentId;
    
    if(parentId === null) {
      tree.push(node);
    } else {
      (this[parentId].children || (this[parentId].children = [])).push(node);
    }
  }, data.reduce(function(hash, node) {
    hash[node._id] = node;
    
    return hash;
  }, Object.create(null)));
  
  return tree;
}

var data = [{
    _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,
}];

var result = createTree(data);

console.log(result);

Comments