// pid 代表属于的父级 id
// id 代表的是自己本身的id,本身的 id 是多少
let flatArr = [
{ id: 1, name: "部门1", pid: 0 },
{ id: 2, name: "部门2", pid: 1 },
{ id: 3, name: "部门3", pid: 1 },
{ id: 4, name: "部门4", pid: 3 },
{ id: 5, name: "部门5", pid: 4 },
];
// 预期输出
// [
// {
// id: 1,
// name: "部门1",
// pid: 0,
// children: [
// { id: 2, name: "部门2", pid: 1 },
// {
// id: 3,
// name: "部门3",
// pid: 1,
// children: [
// {
// id: 4,
// name: "部门4",
// pid: 3,
// children: [{ id: 5, name: "部门5", pid: 4 }],
// },
// ],
// },
// ],
// },
// ]
// 预期输出:
// 1. 子节点的pid是父节点的id,即某个对象的 pid 与 某个对象的 id 相同,则前者为后者的子节点
// 2. 返回为带有层级的对象数组
// 步骤
// 为了避免使用递归导致的性能较差,每次遍历一遍数字,这里使用 map 存储对象
// 1.先将每个对象变为通过 id 保存的具体对象的map 对象
// 2.创建结果数组
// 3.遍历传入的数组,根据传入的 parent_id(pid),获取所有父节点的对象,push 到数组中,作为第一层对象
// 4.在遍历数组过程中,获取数组的 pid,从刚才保存的对象中寻找父级对象是否存在如果存在,增加 children 属性,数组,并 push 当前对象
// arr 为传入的待转换的扁平数组
// parentId 为根节点 id
function arrayToTree(arr, parentId) {
// 将所有对象存到 map 中
const map = arr.reduce((prev, cur) => {
// 注意:这里是浅拷贝,会修改原数组,当后续再使用原数组会出问题
prev[cur.id] = cur;
return prev;
}, {});
// 定义返回结果数组
let result = [];
// 遍历传入的对象
for (let i = 0; i < arr.length; i++) {
const item = arr[i];
// 当遍历到的对象的 pid 等于 传入的根节点的 id,说明为根节点,直接 push 到数组中
if (item.pid === parentId) {
result.push(item);
// 退出本次循环
continue;
}
// 如果不是根节点,从 map 中找到 pid 对应的对象,该对象即为当前遍历到的对象的父节点
const parent = map[item.pid];
if (parent) {
// 给父节点添加 children 属性,并定义为数组
parent.children = parent.children || [];
// 在数组中 push 当前子节点
parent.children.push(item);
}
}
return result;
}
console.log(arrayToTree(flatArr, 0));
// 不改变原数组的方法
function arrayToTree2(items) {
const result = []; // 存放结果集
const itemMap = {}; //
for (const item of items) {
const id = item.id;
const pid = item.pid;
if (!itemMap[id]) {
itemMap[id] = {
children: [],
};
}
itemMap[id] = {
...item,
children: itemMap[id]["children"],
};
const treeItem = itemMap[id];
if (pid === 0) {
result.push(treeItem);
} else {
if (!itemMap[pid]) {
itemMap[pid] = {
children: [],
};
}
itemMap[pid].children.push(treeItem);
}
}
return result;
}
console.log(arrayToTree2(flatArr));
let treeArr = [
{
id: 1,
name: "部门1",
pid: 0,
children: [
{ id: 2, name: "部门2", pid: 1 },
{
id: 3,
name: "部门3",
pid: 1,
children: [
{
id: 4,
name: "部门4",
pid: 3,
children: [{ id: 5, name: "部门5", pid: 4 }],
},
],
},
],
},
];
// 树形结构转为扁平数组
function flatten(arr) {
return arr.reduce((prev, cur) => {
const { children = [], ...others } = cur;
return prev.concat([{ ...others }], flatten(children));
}, []);
}
console.log("树形数组转为扁平数组");
console.log(flatten(treeArr));
console.log(treeArr);
注意:
转载请注明出处:https://cloud.tencent.com/developer/article/2121030
参考链接: