Flat array to tree array using lodash.js


I am trying to convert a flat array to an array of arrays since I will use the data in jsTree. I also need to convert key names such as "Name" to "text".
I want to use lodash.js, but I'm really new to lodash. I was looking for a solution, but could not find a suitable one for my case.
So can you help with this? The following are data with flat arrays:

[
    {
        Id:1,
        Name: 'name1',
        Parent: 0
    },
    {
        Id:2,
        Name: 'name2',
        Parent: 1
    },
    {
        Id:3,
        Name: 'name3',
        Parent: 2
    },
    {
        Id:4,
        Name: 'name4',
        Parent: 1
    },
    {
        Id:5,
        Name: 'name5',
        Parent: 1
    },
    {
        Id:6,
        Name: 'name6',
        Parent: 5
    }
]

I would like to have tree data such as:

{
    "id": 1, 
    "text" : "name1", 
    "children" : [
        { 
            "id": 2, 
            "text" : "name2", 
            "children" : [{
                "id": 3,
                "text": "name3"
            }] 
        },
        { 
            "id": 4, 
            "text" : "name4" 
        },
        { 
            "id": 5, 
            "text" : "name5",
            "children" : [{
                "id": 6,
                "text": "name6"
            }]  
        }
    ]
}

Thank you in advance

+4
source share
4 answers

This sentence is in plain Javascript for unsorted data.

var data = [{ Id: 1, Name: 'name1', Parent: 0 }, { Id: 2, Name: 'name2', Parent: 1 }, { Id: 3, Name: 'name3', Parent: 2 }, { Id: 4, Name: 'name4', Parent: 1 }, { Id: 5, Name: 'name5', Parent: 1 }, { Id: 6, Name: 'name6', Parent: 5 }],
    tree = function (data, root) {
        var r;
        data.forEach(function (a) {
            this[a.Id] = { id: a.Id, text: a.Name, children: this[a.Id] && this[a.Id].children };
            if (a.Parent === root) {
                r = this[a.Id];
            } else {
                this[a.Parent] = this[a.Parent] || {};
                this[a.Parent].children = this[a.Parent].children || [];
                this[a.Parent].children.push(this[a.Id]);
            }
        }, Object.create(null));
        return r;
    }(data, 0);

document.write('<pre>' + JSON.stringify(tree, 0, 4) + '</pre>');
Run codeHide result
+2

, , :

var t = [{ Id: 1, Name: 'name1', Parent: 0 }, { Id: 2, Name: 'name2', Parent: 1 }, { Id: 3, Name: 'name3', Parent: 2 }, { Id: 4, Name: 'name4', Parent: 1 }, { Id: 5, Name: 'name5', Parent: 1 }, { Id: 6, Name: 'name6', Parent: 5 }];

var elements = [];
t.forEach(function(element) {
	elements[element.Id] = {
		id: element.Id,
		text: element.Name,
		parent: element.Parent,
		children: []
	}
});

elements.forEach(function(element) {
	elements[element.parent] && elements[element.parent].children.push(element);
	delete element.parent;
})

document.write(['<pre>', JSON.stringify(elements[1], 0, 3), '</pre>'].join(''));
Hide result
+1

-

return _(data).map(function(val) { val.children = []; })
.map(function(val, key) {
    data[val.parent].children.push(val);
});

Violates the indexing of arrays. You may need to first create an auxiliary map from Idto indexin the source data.

This is just vanilla use Array.map, so lodash is not required for this solution.

0
source

The function below builds a tree from a list of objects. It is not hard in any format.

function buildTree(flatList, idFieldName, parentKeyFieldName, fieldNameForChildren) {
    var rootElements = [];
    var lookup = {};

    flatList.forEach(function (flatItem) {
      var itemId = flatItem[idFieldName];
      lookup[itemId] = flatItem;
      flatItem[fieldNameForChildren] = [];
    });

    flatList.forEach(function (flatItem) {
      var parentKey = flatItem[parentKeyFieldName];
      if (parentKey != null) {
        var parentObject = lookup[flatItem[parentKeyFieldName]];
        if(parentObject){
          parentObject[fieldNameForChildren].push(flatItem);
        }else{
          rootElements.push(flatItem);
        }
      } else {
        rootElements.push(flatItem);
      }

    });

    return rootElements;
  }

Here is the fiddle using your example as input.

The original source comes from this answer .

0
source

All Articles