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 };
|