Several ways of writing js array to tree

Generally, the data we get from the backend is completely tiled, such as the following code, but when we generate a tree menu, we need to generate tree data, like 1 => 1-1 => 1-1-1, 2 => 2-1 => 2-1-1 There are several ways to convert a flat array into a tree array


1. Non-recursive method①

const arr = [
  { id: '00', name: '测试', pid: '', job: '测试' },
  { id: '01', name: '张大', pid: '', job: '项目经理' },

  { id: '02', name: '小亮', pid: '01', job: '产品leader' },
  { id: '03', name: '小美', pid: '01', job: 'UIleader' },
  { id: '04', name: '老马', pid: '01', job: '技术leader' },
  { id: '05', name: '老王', pid: '01', job: '测试leader' },
  { id: '06', name: '老李', pid: '01', job: '运维leader' },

  { id: '07', name: '小丽', pid: '02', job: '产品经理' },
  { id: '08', name: '大光', pid: '02', job: '产品经理' },
  { id: '09', name: '小高', pid: '03', job: 'UI设计师' },
  { id: '10', name: '小刘', pid: '04', job: '前端工程师' },
  { id: '11', name: '小华', pid: '04', job: '后端工程师' },
  { id: '12', name: '小李', pid: '04', job: '后端工程师' },
  { id: '13', name: '小赵', pid: '05', job: '测试工程师' },
  { id: '14', name: '小强', pid: '05', job: '测试工程师' },
  { id: '15', name: '小涛', pid: '06', job: '运维工程师' }
]
const transList2TreeData = arr => {
  // 最终树形数组
  const treeData = []
  // 深拷贝
  const arrClone = JSON.parse(JSON.stringify(arr))
  // 映射表 => 快速找到上级
  const mapInfo = arrClone.reduce((obj, item) => {
    item.children = []
    obj[item.id] = item
    return obj
  }, {})
  // console.log('转树函数map', mapInfo)
  // 转树
  arrClone.forEach(item => {
    const parent = mapInfo[item.pid]
    // 如果父节点存在, 直接push到父级的children数组里面
    // 如果父级不存在, 说明本身就是一级, 直接push到treeData数组
    parent ? parent.children.push(item) : treeData.push(item)
  })
  // 打印结果
  console.log(treeData)
  console.log(arr) // 查看原数组是否有变化
  return treeData
}
transList2TreeData(arr)

2. Non-recursive method②

const arr = [
  { id: '00', name: '测试', pid: '', job: '测试' },
  { id: '01', name: '张大', pid: '', job: '项目经理' },
  
  { id: '02', name: '小亮', pid: '01', job: '产品leader' },
  { id: '03', name: '小美', pid: '01', job: 'UIleader' },
  { id: '04', name: '老马', pid: '01', job: '技术leader' },
  { id: '05', name: '老王', pid: '01', job: '测试leader' },
  { id: '06', name: '老李', pid: '01', job: '运维leader' },
  
  { id: '07', name: '小丽', pid: '02', job: '产品经理' },
  { id: '08', name: '大光', pid: '02', job: '产品经理' },
  { id: '09', name: '小高', pid: '03', job: 'UI设计师' },
  { id: '10', name: '小刘', pid: '04', job: '前端工程师' },
  { id: '11', name: '小华', pid: '04', job: '后端工程师' },
  { id: '12', name: '小李', pid: '04', job: '后端工程师' },
  { id: '13', name: '小赵', pid: '05', job: '测试工程师' },
  { id: '14', name: '小强', pid: '05', job: '测试工程师' },
  { id: '15', name: '小涛', pid: '06', job: '运维工程师' }
]

function trans2TreeData(arr) {
  const cloneData = JSON.parse(JSON.stringify(arr)) // 深拷贝避免影响源数据
  return cloneData.filter(father => {
    // 循环所有项,并添加children属性
    const branchArr = cloneData.filter(child => father.id === child.pid) // 筛选出此项的所有子元素
    branchArr.length > 0 ? (father.children = branchArr) : false // 给父级添加一个children属性,并赋值
    // father.children = branchArr // 如果希望每个元素无论有没有children都添加children属性  可以直接赋值
    return father.pid === '' // 返回pid为''的顶级节点
  })
}

const result = trans2TreeData(arr)
console.log(result)

3. Recursive method

const arr = [
  { id: '00', name: '测试', pid: '', job: '测试' },
  { id: '01', name: '张大', pid: '', job: '项目经理' },

  { id: '02', name: '小亮', pid: '01', job: '产品leader' },
  { id: '03', name: '小美', pid: '01', job: 'UIleader' },
  { id: '04', name: '老马', pid: '01', job: '技术leader' },
  { id: '05', name: '老王', pid: '01', job: '测试leader' },
  { id: '06', name: '老李', pid: '01', job: '运维leader' },

  { id: '07', name: '小丽', pid: '02', job: '产品经理' },
  { id: '09', name: '小高', pid: '03', job: 'UI设计师' },
  { id: '10', name: '小刘', pid: '04', job: '前端工程师' },
  { id: '13', name: '小赵', pid: '05', job: '测试工程师' },
  { id: '15', name: '小涛', pid: '06', job: '运维工程师' }
]

function transList2TreeData(list, rootValue) {
  const deepList = JSON.parse(JSON.stringify(list)) // 深拷贝
  const arr = []
  deepList.forEach(item => {
    if (item.pid === rootValue) {
      const children = transList2TreeData(deepList, item.id)
      children.length ? (item.children = children) : false
      // item.children = children // 如果希望每个item都有children属性, 可以直接赋值
      arr.push(item)
    }
  })
  return arr
}

const result = transList2TreeData(arr, '')
console.log(result[1].children[0])

Guess you like

Origin blog.csdn.net/qq_59650449/article/details/128517926