最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Flat array to tree array using lodash.js - Stack Overflow

programmeradmin0浏览0评论


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


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

Share Improve this question asked Apr 19, 2016 at 13:34 baris usanmazbaris usanmaz 8491 gold badge15 silver badges32 bronze badges 2
  • is the data sorted - parent wise? – Nina Scholz Commented Apr 19, 2016 at 13:35
  • @NinaScholz yes we can think so. – baris usanmaz Commented Apr 19, 2016 at 13:39
Add a ment  | 

4 Answers 4

Reset to default 2

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>');

If you are not sure if child cannot appear before parent, then you can use this code:

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(''));

The function below builds a tree from a list of objects. It’s not tight to 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 a fiddle using your example as input.

The original source es from this answer.

Something like

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

Abuses array indexing. You may need to build an auxiliary map from Id to index in the source data first.

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

发布评论

评论列表(0)

  1. 暂无评论