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