javascript手写树形结构
方式一:深拷贝循环
const arr1 = [
{ menuId: 1, name: "系统管理1", parentMenu: null, }, { menuId: 2, name: "系统管理2", parentMenu: null, }, { menuId: 3, name: "系统管理1_0", parentMenu: 1, }, { menuId: 4, name: "系统管理1_1", parentMenu: 1, }, { menuId: 5, name: "系统管理2_0", parentMenu: 2, }, { menuId: 6, name: "系统管理2_2_0", parentMenu: 5, }, { menuId: 7, name: "系统管理3", parentMenu: null, }, { menuId: 8, name: "系统管理1-1-2", parentMenu: 4, }, ]; const arr2 = [ { id: 1, name: "1", parentId: null, }, { id: 2, name: "2", parentId: null, }, { id: 3, name: "1_0", parentId: 1, }, ]; function toTree2(arr, Id='id', parentId='parentId', children='children') { // 先copy一份数据 let newA=JSON.parse(JSON.stringify(arr)); return newA.filter(p=>{ //遍历 const c = newA.filter(item=>item[parentId]==p[Id]); //找到就赋值 c.length && (p[children] = c) return p[parentId]==null }) } const resultArr = toTree2(arr1,'menuId','parentMenu','list'); const resultArr1 = toTree2(arr2); arr1[6].name='hedan'; console.log('树形结构', resultArr1);
方式二:递归
var array = [ { pid: 4, id: 6617, name: "a", subNode: [] }, { pid: 5, id: 666, name: "a", subNode: [] }, { pid: 4, id: 6616, name: "a", subNode: [] }, { pid: 6616, id: 66161, name: "a", subNode: [] }, { pid: -1, id: 0, name: "a", subNode: [] }, { pid: 0, id: 4, name: "a", subNode: [] }, { pid: 0, id: 5, name: "a", subNode: [] }, { pid: 4, id: 10, name: "a", subNode: [] }, { pid: 10, id: 451, name: "a", subNode: [] }, { pid: 0, id: 98, name: "a", subNode: [] }, { pid: 98, id: 23, name: "a", subNode: [] }, { pid: 98, id: 523, name: "a", subNode: [] } ]; var toTree = function (tarArray) { var resultTree; var findChildren = tree => { tree.forEach(node => { node.children = tarArray.filter(cNode => cNode.pid === node.id); if (node.children.length) { findChildren(node.children); } } ); } if (tarArray && tarArray.length > 0) { // step1:把跟节点首先放进数组,根节点支持:null 0 "" const tmpTree = tarArray.filter(node => !node.pid); console.log('tmpTree',tmpTree) // step2:递归生成节点及子节点数据 findChildren(tmpTree) resultTree = tmpTree; } // findChildren = null; return resultTree; } console.log(toTree(array));
双层循环
/** * 构造树型结构数据 * @param {*} data 数据源 * @param {*} id id字段 默认 'id' * @param {*} parentId 父节点字段 默认 'parentId' * @param {*} children 孩子节点字段 默认 'children' */ export function handleTree(data, id='id', parentId='parentId', children='children', rootId) { rootId = rootId || Math.min.apply(Math, data.map(item => item[parentId])) || 0; console.log(" father[parentId] === rootId",rootId) //对原数据深度克隆 const cloneData = JSON.parse(JSON.stringify(data)); const treeData = cloneData.filter(father => { let branchArr = cloneData.filter(child => { return father[id] == child[parentId] }) if(branchArr && branchArr.length > 0){ father[children] = branchArr }else{ delete father[children] //重要 去掉空children属性 } // 返回第一层 return father[parentId] == rootId; //注意 不要用===号 这样rootId为"0"时无效 }) return treeData !== "" ? treeData : data; }