递归实现
const menuArray = [
{ id: 1, pageName: "用户管理", pid: 0 },
{ id: 2, pageName: "图书管理", pid: 0 },
{ id: 3, pageName: "销售管理", pid: 0 },
{ id: 4, pageName: "借阅管理", pid: 0 },
{ id: 5, pageName: "系统设置", pid: 0 },
{ id: 6, pageName: "用户类型管理", pid: 1 },
{ id: 7, pageName: "用户信息管理", pid: 1 },
{ id: 8, pageName: "新增用户", pid: 1 },
{ id: 9, pageName: "图书类型管理", pid: 2 },
{ id: 10, pageName: "图书管理", pid: 2 },
{ id: 11, pageName: "入库管理", pid: 3 },
{ id: 12, pageName: "出库管理", pid: 3 },
{ id: 13, pageName: "借书管理", pid: 4 },
{ id: 14, pageName: "还书管理", pid: 4 },
{ id: 15, pageName: "退出", pid: 5 },
{ id: 16, pageName: "用户类型", pid: 6 },
];
function transListToTreeData(list,rootPid) {
const arr = []
list.forEach(item => {
if(item.pid === rootPid) {
// 当前节点的id 和当前节点的子节点的pid是相等的
const children = transListToTreeData(list, item.id)
item .children = children // 将子节点赋值给当前节点
arr.push(item)
}
})
return arr // arr就是树形结构的数据
}
// 输出调用结果
console.log(transListToTreeData(menuArray, 0))
另一种递归封装
const menuArray = [
{ id: 1, pageName: "用户管理", pid: 0 },
{ id: 2, pageName: "图书管理", pid: 0 },
{ id: 3, pageName: "销售管理", pid: 0 },
{ id: 4, pageName: "借阅管理", pid: 0 },
{ id: 5, pageName: "系统设置", pid: 0 },
{ id: 6, pageName: "用户类型管理", pid: 1 },
{ id: 7, pageName: "用户信息管理", pid: 1 },
{ id: 8, pageName: "新增用户", pid: 1 },
{ id: 9, pageName: "图书类型管理", pid: 2 },
{ id: 10, pageName: "图书管理", pid: 2 },
{ id: 11, pageName: "入库管理", pid: 3 },
{ id: 12, pageName: "出库管理", pid: 3 },
{ id: 13, pageName: "借书管理", pid: 4 },
{ id: 14, pageName: "还书管理", pid: 4 },
{ id: 15, pageName: "退出", pid: 5 },
{ id: 16, pageName: "用户类型", pid: 6 },
];
const transListToTreeData2 = (arr, rootPid) => {
const result = []
handleArr(arr, result, rootPid)
return result
}
const handleArr = (arr, result, rootPid) => {
for (const item of arr) {
// 当前项的pid等于父节点的id,就继续从当前项向下递归
if (item.pid === rootPid) {
// 每项都要有一个chldren:[]
const newObj = { ...item, children: [] }
result.push(newObj)
handleArr(arr, newObj.children, item.id)
}
}
}
transListToTreeData2(menuArray , 0)
非递归实现
思路:
新建 treeMap 存放键值对,新建 result 结果数组,
遍历每一项,每项新增一个 children: [],分别记录 id(当前项id) 和 pid(父项id),
特殊情况:当 pid 为0时,表示当前项没有父节点,直接推入结果数组
pid 非 0 时,treeMap[pid] 表示父项,只需往父项的 children 中把子项推入
const menuArray = [
{ id: 2, pageName: "图书管理", pid: 0 },
{ id: 1, pageName: "用户管理", pid: 0 },
{ id: 3, pageName: "销售管理", pid: 0 },
{ id: 4, pageName: "借阅管理", pid: 0 },
{ id: 5, pageName: "系统设置", pid: 0 },
{ id: 6, pageName: "用户类型管理", pid: 1 },
{ id: 7, pageName: "用户信息管理", pid: 1 },
{ id: 8, pageName: "新增用户", pid: 1 },
{ id: 9, pageName: "图书类型管理", pid: 2 },
{ id: 10, pageName: "图书管理", pid: 2 },
{ id: 11, pageName: "入库管理", pid: 3 },
{ id: 12, pageName: "出库管理", pid: 3 },
{ id: 13, pageName: "借书管理", pid: 4 },
{ id: 14, pageName: "还书管理", pid: 4 },
{ id: 15, pageName: "退出", pid: 5 },
{ id: 16, pageName: "用户类型", pid: 6 },
];
const transListToTreeData = (arr) => {
const result = []
const treeMap = {}
for (const item of arr) {
const id = item.id
const pid = item.pid
// 如果 treeMap[id] 还没有创建,就创建一个
if (!treeMap[id]) {
treeMap[id] = {
children: []
}
}
// 每一项都新增一个children:[],为了防止覆盖,使用 children: treeMap[id].children
// treeMap[id] = { ...item, children: []}
treeMap[id] = { ...item, children: treeMap[id].children }
// pid为 0 表示没有父节点
if (pid === 0) {
result.push(treeMap[id])
}
// 如果 treeMap[pid] 还没有创建,就创建一个
if (!treeMap[pid]) {
treeMap[pid] = {
children: []
}
}
// pid 非 0,把当前项推入它父节点的children中
treeMap[pid].children.push(treeMap[id])
}
return result
}
console.log(transListToTreeData(menuArray, 0))