Vue业务场景: 如何把扁平化数据转化成树形数据

2,042 阅读1分钟
  • 在日常的业务场景中, 我们常常需要处理后端返回来的数据, 这里我们就来介绍一种十分典型的数据处理问题
  • 声明: 在平常的业务开发中, 我们不会特别注重一个数据处理算法的性能 (即时间复杂度和空间复杂度), 因为我们前端处理数据, 大多数情况下, 是不会出现性能瓶颈的.

题干: 把扁平化的数组数据, 转换成树形结构的数组数据

    const arr = [
        { id:1, pid: '', name: '老王' },
        { id:2, pid: 1, name: '王一' },
        { id:3, pid: 1, name: '王二' },
        { id:4, pid: '', name: '老孙' },
        { id:5, pid: '4', name: '孙一' },
        { id:6, pid: '4', name: '孙二' },
    ]
    
    
    const targetArr = [
         { id: 1,
           pid: '',
           name: '老王' 
           children: [
               { id: 2, pid: 1, name: '王一' },
               { id: 3, pid: 1, name: '王二' },
           ]
         },
         { id: 4,
           pid: '',
           name: '老孙' 
           children: [
               { id: 5, pid: 4, name: '孙一' },
               { id: 6, pid: 4, name: '孙二' },
           ]
         },
    ]

解答

方法一: (只适合这种,两层嵌套)

  • 核心思想: 两次循环
function arrayToTree(arr) {
  const tree = arr.filter(item => {
    const child = arr.filter(child => child.pid === item.id)
    child.length > 0 ? (item.children = child) : ''
    return item.pid === ''
  })
  return tree
}

方法二: (无论多少层, 都能解决) --- 递归

function arrayToTree(arr, rootNode) {
    const tree = []
    arr.forEach(item => {
      if (item.pid === rootNode) {
      // 找到根节点之后, 就去找下面有没有对应的子节点
      const children = arrayToTree(arr, item.id)
        // 如果 children 的长度大于0, 说明找到了子节点
        children.length > 0 ? (item.children = children) : 0
        tree.push(item) // 将内容加入数组中
      }
    })
    return tree
}
  • 如果你有 更好的答案 或 不同的想法, 欢迎留在评论区