chore: init project
This commit is contained in:
97
packages/@vben-core/shared/toolkit/src/tree.ts
Normal file
97
packages/@vben-core/shared/toolkit/src/tree.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
interface TreeConfigOptions {
|
||||
// 子属性的名称,默认为'children'
|
||||
childProps: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @zh_CN 遍历树形结构,并返回所有节点中指定的值。
|
||||
* @param tree 树形结构数组
|
||||
* @param getValue 获取节点值的函数
|
||||
* @param options 作为子节点数组的可选属性名称。
|
||||
* @returns 所有节点中指定的值的数组
|
||||
*/
|
||||
function traverseTreeValues<T, V>(
|
||||
tree: T[],
|
||||
getValue: (node: T) => V,
|
||||
options?: TreeConfigOptions,
|
||||
): V[] {
|
||||
const result: V[] = [];
|
||||
const { childProps } = options || {
|
||||
childProps: 'children',
|
||||
};
|
||||
|
||||
const dfs = (treeNode: T) => {
|
||||
const value = getValue(treeNode);
|
||||
result.push(value);
|
||||
const children = (treeNode as Record<string, any>)?.[childProps];
|
||||
if (!children) {
|
||||
return;
|
||||
}
|
||||
if (children.length > 0) {
|
||||
for (const child of children) {
|
||||
dfs(child);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const treeNode of tree) {
|
||||
dfs(treeNode);
|
||||
}
|
||||
return result.filter(Boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件过滤给定树结构的节点,并以原有顺序返回所有匹配节点的数组。
|
||||
* @param tree 要过滤的树结构的根节点数组。
|
||||
* @param filter 用于匹配每个节点的条件。
|
||||
* @param options 作为子节点数组的可选属性名称。
|
||||
* @returns 包含所有匹配节点的数组。
|
||||
*/
|
||||
function filterTree<T extends Record<string, any>>(
|
||||
tree: T[],
|
||||
filter: (node: T) => boolean,
|
||||
options?: TreeConfigOptions,
|
||||
): T[] {
|
||||
const { childProps } = options || {
|
||||
childProps: 'children',
|
||||
};
|
||||
|
||||
const _filterTree = (nodes: T[]): T[] => {
|
||||
return nodes.filter((node: Record<string, any>) => {
|
||||
if (filter(node as T)) {
|
||||
if (node[childProps]) {
|
||||
node[childProps] = _filterTree(node[childProps]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
return _filterTree(tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件重新映射给定树结构的节
|
||||
* @param tree 要过滤的树结构的根节点数组。
|
||||
* @param mapper 用于map每个节点的条件。
|
||||
* @param options 作为子节点数组的可选属性名称。
|
||||
*/
|
||||
function mapTree<T, V extends Record<string, any>>(
|
||||
tree: T[],
|
||||
mapper: (node: T) => V,
|
||||
options?: TreeConfigOptions,
|
||||
): V[] {
|
||||
const { childProps } = options || {
|
||||
childProps: 'children',
|
||||
};
|
||||
return tree.map((node) => {
|
||||
const mapperNode: Record<string, any> = mapper(node);
|
||||
if (mapperNode[childProps]) {
|
||||
mapperNode[childProps] = mapTree(mapperNode[childProps], mapper, options);
|
||||
}
|
||||
return mapperNode as V;
|
||||
});
|
||||
}
|
||||
|
||||
export { filterTree, mapTree, traverseTreeValues };
|
Reference in New Issue
Block a user