实现扁平数据转化为树形数据

递归实现

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))

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值