返回 AiToEarn
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: any[], key: string | number, value: any) {
34 const filterChildrenTree = (resTree: any[], treeItem: { [x: string]: string | any[], children: any[] }) => {
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)
45 resTree.push({ ...data })
46 }
47 return resTree
48 }
49 return treeData.reduce(filterChildrenTree, [])
50 }
51
52 /**
53 * 过滤树,并保留原有的结构
54 * @param treeData
55 * @param predicate
56 */
57 export function filterTree<T extends TreeNode>(
58 treeData: TreeNode<T>[],
59 predicate: (data: T) => boolean,
60 ): TreeNode<T>[] {
61 function filter(treeData: TreeNode<T>[]): TreeNode<T>[] {
62 if (!treeData?.length)
63 return treeData
64
65 return treeData.filter((data) => {
66 if (!predicate(data))
67 return false
68
69 data.children = filter(data.children!)
70 return true
71 })
72 }
73
74 return filter(treeData) || []
75 }
76
77 export function deleteEmptyChildren(arr: any) {
78 arr?.forEach((node: { children: any }) => {
79 if (node.children?.length === 0)
80 delete node.children
81 else deleteEmptyChildren(node.children)
82 })
83 }
84
84 lines TYPESCRIPT