场景说明
在工作中通常会遇到一维数组转多维数组的情况,比如后台动态返回router路由动态数据,地域三级联动、菜单嵌套等等。我们需要根据返回的扁平化数据进行处理
双循环找到匹配项,进行递归
let arr = [
{
id: 1,
pid: 0,
name: '父1'
},
{
id: 2,
pid: 0,
name: '父2'
},
{
id: 3,
pid: 0,
name: '父3'
},
{
id: 4,
pid: 1,
name: '父1-子1'
},
{
id: 5,
pid: 1,
name: '父1-子2'
},
{
id: 6,
pid: 5,
name: '父1-子2-孙1'
},
{
id: 7,
pid: 2,
name: '父2-子1'
}
]
// 数据处理
function dealArr (arr) {
arr.forEach(gitem => {
arr.forEach(item => {
// 判断父子嵌套
if (gitem.id === item.pid) {
gitem.children = gitem.children || []
gitem.children.push(item)
}
})
// 递归寻找子集的父子嵌套
if (gitem.children && gitem.children.length > 0) {
dealArr(gitem.children)
}
})
}
// 因为是对数组的引用处理完成后的数组还包含所有的子节点
let newArr = []
arr.forEach(item => {
//去掉所有的子节点
if (item.pid === 0) {
newArr.push(item)
}
})
对象指针查找
function dealNewArr (arr) {
// 找出唯一值生成指针对象
let map = {}
arr.forEach(item => {
map[item.id] = item
})
// 结果数组
let result = []
arr.forEach(child => {
// 找出每一个和指针对象相对应的子节点
const mapItem = map[child.pid]
if (mapItem) {
(mapItem.children || (mapItem.children = [])).push(child)
} else {
// 处理好的数据或者没有子节点直接添加到结果数组
result.push(child)
}
})
return result
}