树的相关操作

平铺数组<=>树形结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const arr = [
{ id: "001", name: "节点1", pid: "" },
{ id: "0011", pid: "001", name: "节点1-1" },
{ id: "00111", pid: "0011", name: "节点1-1-1" },
{ id: "002", name: "节点2", pid: "" },
];

const generateTree = (arr) => {
return arr.filter((item) => {
item.children = arr.filter((childitem) => {
return item.id === childitem.pid;
});
return !item.pid; // undefined null 0 ''
});
};
tree = generateTree(arr);
console.log(tree);

function TreeToArr(treeData, result = [], { childrenName = "children" } = {}) {
treeData.forEach((treeItem) => {
result.push(treeItem);
if (treeItem[childrenName]) {
TreeToArr(treeItem[childrenName], result);
delete treeItem[childrenName];
}
});
return result;
}

console.log(TreeToArr(tree));

树的遍历查看祖先节点

树的全部展开操作,一般需要获取到所有的树的组件节点key

树的数据结构

1
2
3
4
5
interface TNode {
title: string;
key: number;
children: TNode[];
}

查看所有的父节点

1
2
3
4
5
6
7
8
9
function getAllParentKeys(list: TNode[]) {
const keys: number[] = [];
list.forEach(({ key, children }) => {
if (children.length > 0) {
keys.push(key, ...getAllParentKeys(children));
}
});
return keys;
}

查找某个指定节点的所有祖先节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 找到某个节点的所有祖先节点
function findParentKeys(list: TNode[], childKey: number) {
const resultKey: number[] = [];
canFindKey(list, childKey, resultKey);
return resultKey;
}

function canFindKey(list: TNode[], childKey: number, result: number[]) {
let canFind = false;
// 这里的遍历需要注意!使用some return true可以跳出some循环
// 如果使用forEach return只能跳出当前循环,但是不能终止forEach,可以使用try catch终止
list.some(({ key, children }) => {
if (key === childKey) {
canFind = true;
return true;
}
if (children.length > 0) {
result.push(key);
canFind = canFindKey(children, childKey, result);
if (canFind) {
return true;
}
result.pop();
}
return false;
});
return canFind;
}