1、查看扁平数据以及输出结果:
扁平数据结构如下:
let arr = [ {id: 1, name: '部门1', pid: 0}, {id: 2, name: '部门2', pid: 1}, {id: 3, name: '部门3', pid: 1}, {id: 4, name: '部门4', pid: 3}, {id: 5, name: '部门5', pid: 4}, ]
输出结果数据:
[ { "id": 1, "name": "部门1", "pid": 0, "children": [ { "id": 2, "name": "部门2", "pid": 1, "children": [] }, { "id": 3, "name": "部门3", "pid": 1, "children": [ // 结果 ,,, ] } ] } ]
2、以上例子的几种解决方案
1> 主要思路也是先把数据转成Map
去存储,之后遍历的同时借助对象的引用
,直接从Map
找对应的数据做存储。不同点在遍历的时候即做Map
存储,有找对应关系。
function arrayToTree(items) { const result = []; // 存放结果集 const itemMap = {}; // for (const item of items) { const id = item.id; const pid = item.pid; if (!itemMap[id]) { itemMap[id] = { children: [], } } itemMap[id] = { ...item, children: itemMap[id]['children'] } const treeItem = itemMap[id]; if (pid === 0) { result.push(treeItem); } else { if (!itemMap[pid]) { itemMap[pid] = { children: [], } } itemMap[pid].children.push(treeItem) } } return result; }
2> 主要思路是先根据pid进行由大到小排序之后,循环数据进行填充children,最后过滤数据第一级
function arrToTree(arr) { arr .sort((a, b) => b.pid - a.pid) .forEach((v) => { const pan = arr.filter((g) => g.id === v.pid)[0] || {}; if (pan['children']) { pan['children'].push(v); } else { pan['children'] = [v]; } }); return arr.filter(v => v.pid === 0) } arrToTree(arr);
3> 与第一种方法类似,主要思路也是先把数据转成Map
去存储,之后遍历的同时借助对象的引用
,直接从Map
找对应的数据做存储。更精简(推荐)
function ArrayToTree(array) { array = JSON.parse(JSON.stringify(array)) let result = [] let trees = {} array.forEach(item => { item.children = [] trees[item.id] = item }) array.forEach(item => { if(trees[item.pid]) trees[item.pid].children.push(item) if(item.pid == 0) result.push(item) }) return result; } ArrayToTree(arr)