假设我们有一数据格式如下
let arr = [
{id: 1, name: '部门1', parentId: 0},
{id: 2, name: '部门2', parentId: 1},
{id: 3, name: '部门3', parentId: 1},
{id: 4, name: '部门4', parentId: 3},
{id: 5, name: '部门5', parentId: 4},
]
现在我们要将其转换成一树形结构,那么我们需要如何处理呢?
首先我们肯定想到通过递归方式来处理。代码如下
function arr2tree(arr, parentId) {
let result = [];
// let resuison = function (arr, result, parentId) {
// arr.forEach(item => {
// if (item.parentId === parentId) {
// item.children = [];
// result.push(item);
// resuison(arr, item.children, item.id);
// }
// });
// }
// resuison(arr, result, 0);
// return result;
//或者
let resuison = function (arr, parentId) {
return arr.filter(item => {
return item.parentId === parentId
}).map(item=>{
item.children = resuison(arr,item.id);
return item
})
}
return resuison(arr,parentId);
}
但是以上两种方法的时间复杂度皆为O(2^n)。性能较差。所以我们可以换一种思路,主要思路是先把数据转成Map去存储,之后遍历的同时借助对象的引用,直接从Map找对应的数据做存储,代码如下
function arr2tree(arr,rootParentId) {
let result = [];
let idMap = {};
// 将数据转成map类型
arr.forEach(item => {
idMap[item.id] = {
...item,
children: []
};
});
// 循环数据,通过对象的引用进行处理
arr.forEach(item=>{
let {id,parentId} = item;
if(parentId === rootParentId) {
result.push(idMap[id]);
} else {
if(!idMap[parentId]) {
idMap[parentId] = {
children:[]
}
}
idMap[parentId].children.push(idMap[id]);
}
})
return result;
}
通过此方法,整个方法的时间复杂度为O(n)。在面对大数据量的情况下,性能会好很多