1.递归处理
let arr = [
{ id: 1, name: "部门1", pid: 0 },
{ id: 2, name: "部门2", pid: 1 },
{ id: 3, name: "部门3", pid: 2 },
{ id: 4, name: "部门4", pid: 0 },
];
function convert(list) {
// 定义一个递归函数,接受一个节点作为参数,返回它的子树
function buildTree(node) {
// 创建一个空数组,用来存放子节点
let children = []
// 遍历数组,找到当前节点的子节点,并递归调用buildTree函数
for (let item of list) {
if (item.pid === node.id) {
children.push(buildTree(item))
}
}
// 如果子节点不为空,就给当前节点添加children属性
if (children.length > 0) {
node.children = children
}
// 返回当前节点
return node
}
// 创建一个空数组,用来存放根节点
let res = []
// 遍历数组,找到根节点,并调用buildTree函数
for (let item of list) {
if (item.pid === 0) {
res.push(buildTree(item))
}
}
// 返回结果数组
return res
}
2.reduce函数处理
function convert(list) {
let res = [];
// 使用reduce方法遍历数组,创建一个maps对象,将数组中的每个元素以id为键,元素本身为值,存入maps对象中
// reduce方法接受一个回调函数和一个初始值作为参数
// 回调函数接受四个参数:累计值,当前值,当前索引,原数组
// 回调函数的返回值会作为下一次调用的累计值
// 初始值是一个空对象,表示maps对象的初始状态
let maps = list.reduce((res, v) => ((res[v.id] = v), res), {});
console.log(maps, "map2");
// console.timeEnd()
// 使用for...of循环遍历数组,对于每个元素item,判断它的pid是否为0,如果是,说明它是根节点,直接将它push到res数组中;如果不是,说明它有父节点,那么通过maps对象找到它的父节点parent,并在parent上创建或获取一个children属性,将item push到parent.children中
for (const item of list) {
console.log(item, "item");
if (item.pid === 0) {
res.push(item);
continue;
}
if (item.pid in maps) {
const parent = maps[item.pid];
parent.children = parent.children || [];
parent.children.push(item);
}
}
// console.log(map,'map');
// 返回res数组作为最终结果
return res;
}
3.eS6语法和高阶函数
function convert(list) {
// 创建一个map对象,存放id和元素的映射关系
// 使用list.map方法,将数组中的每个元素转换成一个数组,包含id和元素本身
// 使用new Map方法,将这个数组转换成一个map对象
let map = new Map(list.map(item => [item.id, item]))
// 使用filter方法过滤出根节点,同时使用forEach方法给每个元素添加children属性
// filter方法接受一个回调函数作为参数,返回一个新的数组,包含满足回调函数条件的元素
// 回调函数接受三个参数:当前值,当前索引,原数组
// 回调函数的返回值是一个布尔值,表示是否保留当前元素
// forEach方法接受一个回调函数作为参数,对数组中的每个元素执行一次回调函数
// 回调函数接受三个参数:当前值,当前索引,原数组
// 回调函数没有返回值,只是对数组中的元素进行操作
return list.filter(item => {
// 如果pid为0,说明是根节点,直接返回true
if (item.pid === 0) return true
// 否则,通过map对象找到父节点,并将当前元素push到父节点的children中
let parent = map.get(item.pid)
parent.children = parent.children || []
parent.children.push(item)
// 返回false,表示不是根节点
return false
})
}