baris usanmaz baris usanmaz - 4 months ago 117
Javascript Question

Flat array to tree array using lodash.js



I am trying to convert a flat array to tree array since I will use the data in jsTree. Also I need to convert key names like "Name" to "text".

I want to use lodash.js but I am realy newbie on lodash. I searched about the solution but I could not find any to fit my case.

So can you help on this? My flat array data is below:

[
{
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 like:

{
"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

Answer

This is a proposal 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>');