根据数据之间的依赖关系,转换成树形结构,比如以pid来连接他们的依赖。

说明: 代码有用到ES6的一些方法,如果不支持ES6的请自行替换

测试数据

[ {"id":1,"name":"根节点1","pid":"0"}, {"id":2,"name":"金字塔1","pid":"1"}, {"id":3,"name":"金字塔2","pid":"1"}, {"id":6,"name":"金字塔2-1","pid":"3"}, {"id":5,"name":"金字塔1-1","pid":"2"}, {"id":8,"name":"金字塔1-1-1","pid":"5"}, {"id":9,"name":"金字塔2-1-1","pid":"6"}, {"id":10,"name":"金字塔1-1-1-1","pid":"8"}, {"id":11,"name":"金字塔1-2","pid":"2"}, {"id":12,"name":"金字塔1-2-1","pid":"11"}, {"id":13,"name":"金字塔1-2-1-1","pid":"12"}, {"id":14,"name":"金字塔2-2","pid":"3"}, {"id":15,"name":"金字塔2-3","pid":"3"}, {"id":16,"name":"金字塔2-4","pid":"3"}, {"id":17,"name":"金字塔1-2-1-1","pid":"12"}, {"id":18,"name":"金字塔1-1-2","pid":"5"}, {"id":19,"name":"金字塔2-1-1-1","pid":"9"}, {"id":20,"name":"金字塔2-1-1-2","pid":"9"}, {"id":23,"name":"金字塔3","pid":"24"}, {"id":24,"name":"根节点2","pid":"0"}, {"id":25,"name":"金字塔4","pid":"24"}, {"id":26,"name":"金字塔3-1","pid":"23"}, {"id":27,"name":"金字塔4-1","pid":"25"}, {"id":28,"name":"金字塔1-1-1-1-1","pid":"10"}, {"id":29,"name":"金字塔1-1-1-1-1-1","pid":"28"}, {"id":30,"name":"金字塔1-1-1-1-1-1-1","pid":"29"}, {"id":31,"name":"金字塔1-1-2-1","pid":"18"}, {"id":32,"name":"金字塔1-1-2-1-1","pid":"31"}, {"id":33,"name":"金字塔1-1-2-1-1-1","pid":"32"} ]

发现了一个写的比我好的方法点击跳转到何泽弘的博客吧

用法

let data = arrayToTree(data, 'id', 'pid'); console.log(data)//转换之后的数据,请看下面

转换之后的树形结构

[{"id":1,"name":"金字塔","pid":"0","childs":[{"id":2,"name":"金字塔1","pid":"1","childs":[{"id":5,"name":"金字塔1-1","pid":"2","childs":[{"id":8,"name":"金字塔1-1-1","pid":"5","childs":[{"id":10,"name":"金字塔1-1-1-1","pid":"8","childs":[{"id":28,"name":"金字塔1-1-1-1-1","pid":"10","childs":[{"id":29,"name":"金字塔1-1-1-1-1-1","pid":"28","childs":[{"id":30,"name":"金字塔1-1-1-1-1-1-1","pid":"29"}]}]}]}]},{"id":18,"name":"金字塔1-1-2","pid":"5","childs":[{"id":31,"name":"金字塔1-1-2-1","pid":"18","childs":[{"id":32,"name":"金字塔1-1-2-1-1","pid":"31","childs":[{"id":33,"name":"金字塔1-1-2-1-1-1","pid":"32"}]}]}]}]},{"id":11,"name":"金字塔1-2","pid":"2","childs":[{"id":12,"name":"金字塔1-2-1","pid":"11","childs":[{"id":13,"name":"金字塔1-2-1-1","pid":"12"},{"id":17,"name":"金字塔1-2-1-1","pid":"12"}]}]}]},{"id":3,"name":"金字塔2","pid":"1","childs":[{"id":6,"name":"金字塔2-1","pid":"3","childs":[{"id":9,"name":"金字塔2-1-1","pid":"6","childs":[{"id":19,"name":"金字塔2-1-1-1","pid":"9"},{"id":20,"name":"金字塔2-1-1-2","pid":"9"}]}]},{"id":14,"name":"金字塔2-2","pid":"3"},{"id":15,"name":"金字塔2-3","pid":"3"},{"id":16,"name":"金字塔2-4","pid":"3"}]}]},{"id":24,"name":"金字塔嘿嘿嘿","pid":"0","childs":[{"id":23,"name":"金字塔3","pid":"24","childs":[{"id":26,"name":"金字塔3-1","pid":"23"}]},{"id":25,"name":"金字塔4","pid":"24","childs":[{"id":27,"name":"金字塔4-1","pid":"25"}]}]}]

具体的实现

/** * 数组转数型结构 * @param data 原始数据 * @param groupKey 分组的key * @param itemKey 分组的key对应数据的那个key 比如pid的值对应的是某一条数据的id */ function arrayToTree(data, groupKey, itemKey){ let rootData = [] //首先根据pid来分组 let groupData = {} data.forEach(item => { if (groupData[item[groupKey]]) { groupData[item[groupKey]] = [...groupData[item[groupKey]], item] } else { groupData[item[groupKey]] = [item] } }) //这里先查找出根节点 let roots = Object.keys(groupData); for (let i = 0; i < data.length; i++) { let isRoot = true; let item = roots[i]; for (let j = 0; j < len; j++) { let item = data[j]; if (item.id == i) { isRoot = false; break; } } if (isRoot) { rootData = groupData[roots[i]]; delete groupData[roots[i]]; roots.splice(i, 1); break; } } this.insert(rootData, groupData, itemKey); return rootData; } //插入数据 function insert(rootData, groupData, itemKey){ Object.keys(groupData).forEach(key => { this.insertChild(rootData, key, groupData[key], itemKey, groupData) }) //判断数据是否有流出数据,一般是根节点在该数据后面,就会产生找不到节点插入,所以会流出 if (JSON.stringify(groupData) != "{}") { this.insert(rootData, groupData); } } // 插入子节点 function insertChild(source, groupkey, childs, itemKey, groupData){ for (let i = 0, len = source.length; i < len; i++) { let item = source[i]; if (item[itemKey] == groupkey) { if (item['childs']) { item['childs'] = [...item['childs'], ...childs]; } else { item['childs'] = childs } delete groupData[groupkey]; break; } else { if (item['childs']) { this.insertChild(item['childs'], groupkey, childs, itemKey, groupData); } } } }

29条数据, 最大层级是8层,转换时间300ms-500ms之间,耗时应该有点大,欢迎有大神在评论区留下更好的方法。

在说一句,有人说先把数据转换成字典???,说是可以提升性能,这个就懵逼了,没听说过字典是什么…