有时咱们须要从扁平的数组构造(flat array),依据id,和pid构建出树形数组构造(tree array),这种情景经常出现在嵌套的目录构造,如下图:
或者企业的部门架构,也会呈现下面的相似构造。
相似下面的情景,如果咱们有以下的数据:
let entries = [{ "id": "12", "parentId": "0", "text": "Man", "level": "1", "children": null }, { "id": "7", "parentId": "12", "text": "Other", "level": "2", "children": null }, { "id": "8", "parentId": "7", "text": "Bird", "level": "3", "children": null }, { "id": "9", "parentId": "0", "text": "Woman", "level": "1", "children": null }, { "id": "11", "parentId": "9", "text": "Girl", "level": "2", "children": null }];
咱们期待通过一个算法,构建出上面的构造:
[ { "id": "12", "parentId": "0", "text": "Man", "level": "1", "children": [ { "id": "7", "parentId": "12", "text": "Other", "level": "2", "children": [ { "id": "8", "parentId": "7", "text": "Bird", "level": "3", "children": [] } ] } ] }, { "id": "9", "parentId": "0", "text": "Woman", "level": "1", "children": [ { "id": "11", "parentId": "9", "text": "Girl", "level": "2", "children": [] } ] }]
兴许咱们能够想到,在遍历数组的时候应用递归。没错能够解决问题,然而这种形式并不高效。
最近,在Stack Overflow上看到一个办法,感觉不错,贴出来分享一下:
function list_to_tree(list) { var map = {}, node, roots = [], i; for (i = 0; i < list.length; i += 1) { map[list[i].id] = i; // initialize the map list[i].children = []; // initialize the children } for (i = 0; i < list.length; i += 1) { node = list[i]; if (node.parentId !== "0") { // if you have dangling branches check that map[node.parentId] exists list[map[node.parentId]].children.push(node); } else { roots.push(node); } } return roots;}
算法的复杂度是(n log(n))。
如果应用递归,那么复杂度是(n^2)。如果数据集比拟大,那么执行的工夫会很长。