返回 AiToEarn
list2tree.util.ts
根目录 / project / aitoearn-electron / server / src / util / list2tree.util.ts
1 export type TreeNode<T = any> = T & {
2 id: number;
3 parentId: number;
4 children?: TreeNode<T>[];
5 };
6
7 export type ListNode<T extends object = any> = T & {
8 id: number;
9 parentId: number;
10 };
11
12 export function list2Tree<T extends ListNode[]>(
13 items: T,
14 parentId: number | null = null,
15 ): TreeNode<T[number]>[] {
16 return items
17 .filter((item) => item.parentId === parentId)
18 .map((item) => {
19 const children = list2Tree(items, item.id);
20 return {
21 ...item,
22 ...(children.length ? { children } : null),
23 };
24 });
25 }
26
27 /**
28 * 过滤树,返回列表数据
29 * @param treeData
30 * @param key 用于过滤的字段
31 * @param value 用于过滤的值
32 */
33 export function filterTree2List(treeData, key, value) {
34 const filterChildrenTree = (resTree, treeItem) => {
35 if (treeItem[key].includes(value)) {
36 resTree.push(treeItem);
37 return resTree;
38 }
39 if (Array.isArray(treeItem.children)) {
40 const children = treeItem.children.reduce(filterChildrenTree, []);
41
42 const data = { ...treeItem, children };
43
44 if (children.length) resTree.push({ ...data });
45 }
46 return resTree;
47 };
48 return treeData.reduce(filterChildrenTree, []);
49 }
50
51 /**
52 * 过滤树,并保留原有的结构
53 * @param treeData
54 * @param predicate
55 */
56 export function filterTree<T extends TreeNode>(
57 treeData: TreeNode<T>[],
58 predicate: (data: T) => boolean,
59 ): TreeNode<T>[] {
60 function filter(treeData: TreeNode<T>[]): TreeNode<T>[] {
61 if (!treeData?.length) return treeData;
62
63 return treeData.filter((data) => {
64 if (!predicate(data)) return false;
65
66 data.children = filter(data.children);
67 return true;
68 });
69 }
70
71 return filter(treeData) || [];
72 }
73
74 export function deleteEmptyChildren(arr: any) {
75 arr?.forEach((node) => {
76 if (node.children?.length === 0) delete node.children;
77 else deleteEmptyChildren(node.children);
78 });
79 }
80
80 lines TYPESCRIPT