oa_based/src/utils/list2tree.util.ts

82 lines
1.9 KiB
TypeScript

export type TreeNode<T = any> = T & {
id: number;
parentId: number;
children?: TreeNode<T>[];
};
export type ListNode<T extends object = any> = T & {
id: number;
parentId: number;
};
export function list2Tree<T extends ListNode[]>(
items: T,
parentId: number | null = null
): TreeNode<T[number]>[] {
return items
.filter(item => item.parentId === parentId)
.map(item => {
const children = list2Tree(items, item.id);
return {
...item,
...(children.length ? { children } : null)
};
});
}
/**
* 过滤树,返回列表数据
* @param treeData
* @param key 用于过滤的字段
* @param value 用于过滤的值
* @returns
*/
export function filterTree2List(treeData, key, value) {
const filterChildrenTree = (resTree, treeItem) => {
if (treeItem[key].includes(value)) {
resTree.push(treeItem);
return resTree;
}
if (Array.isArray(treeItem.children)) {
const children = treeItem.children.reduce(filterChildrenTree, []);
const data = { ...treeItem, children };
if (children.length) resTree.push({ ...data });
}
return resTree;
};
return treeData.reduce(filterChildrenTree, []);
}
/**
* 过滤树,并保留原有的结构
* @param treeData
* @param predicate
* @returns
*/
export function filterTree<T extends TreeNode>(
treeData: TreeNode<T>[],
predicate: (data: T) => boolean
): TreeNode<T>[] {
function filter(treeData: TreeNode<T>[]): TreeNode<T>[] {
if (!treeData?.length) return treeData;
return treeData.filter(data => {
if (!predicate(data)) return false;
data.children = filter(data.children);
return true;
});
}
return filter(treeData) || [];
}
export function deleteEmptyChildren(arr: any) {
arr?.forEach(node => {
if (node.children?.length === 0) delete node.children;
else deleteEmptyChildren(node.children);
});
}