前端 map方法 解决扁平数据结构转Tree
假设后台返回一个扁平的数据结构,我们要转成tree树的结构出来。当然这一般都是后端处理好,我们前端直接拿来接口用就行了。但是后端有时候可能比较忙,那我们前端自己搞。
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": [ // 结果 ,,, ] } ] } ]
我这里只写了最优性能。建议也用这个方法,不用考虑递归方法和两次遍历,我这里一次遍历就搞定了。
主要思路也是先把数据转成Map去存储, 之后遍历的同时借助对象的引用, 直接从Map找对应的数据做存储。 不同点在遍历的时候即做Map存储,有找对应关系。性能会更好。
封装成方法最实用 function ToTree(items) { const result = []; // 存放结果集 const itemMap = {}; // for (const item of items) { const id = item.id; const pid = item.pid; // 先转成map存储 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; }
即:项目中的用法
let items = [ {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}, ] let newArr = items.map(item=>{ const result = []; // 存放结果集 const itemMap = {}; // // 先转成map存储 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) } } console.log(result) return result;})
看图,就是我们想要的结果了 下边是两次循环的 ,可以不看。
function arrayToTree(items) { const result = []; // 存放结果集 const itemMap = {}; // // 先转成map存储 for (const item of items) { itemMap[item.id] = {...item, children: []} } for (const item of items) { const id = item.id; const pid = item.pid; const treeItem = itemMap[id]; if (pid === 0) { result.push(treeItem); } else { if (!itemMap[pid]) { itemMap[pid] = { children: [], } } itemMap[pid].children.push(treeItem) } } return result; }
递归方法 (主要思路是提供一个递getChildren的方法,该方法递归去查找子集。 就这样,不用考虑性能,无脑去查)
/** * 递归查找,获取children */ const getChildren = (data, result, pid) => { for (const item of data) { if (item.pid === pid) { const newItem = {...item, children: []}; result.push(newItem); getChildren(data, newItem.children, item.id); } } } /** * 转换方法 */ const arrayToTree = (data, pid) => { const result = []; getChildren(data, result, pid) return result; }