下面我将介绍几种在 JavaScript 中递归遍历树结构并返回符合条件的子集的方法。
function findSubtree(tree, condition) {
if (condition(tree)) {
return tree;
}
if (tree.children && tree.children.length) {
for (let child of tree.children) {
const result = findSubtree(child, condition);
if (result) {
return result;
}
}
}
return null;
}
// 使用示例
const tree = {
id: 1,
name: 'Root',
children: [
{
id: 2,
name: 'Child 1',
children: [
{ id: 4, name: 'Grandchild 1', children: [] }
]
},
{
id: 3,
name: 'Child 2',
children: [
{ id: 5, name: 'Grandchild 2', children: [] }
]
}
]
};
const result = findSubtree(tree, node => node.id === 5);
console.log(result); // 输出 { id: 5, name: 'Grandchild 2', children: [] }
function findAllNodes(tree, condition) {
let results = [];
if (condition(tree)) {
results.push(tree);
}
if (tree.children && tree.children.length) {
for (let child of tree.children) {
results = results.concat(findAllNodes(child, condition));
}
}
return results;
}
// 使用示例
const allResults = findAllNodes(tree, node => node.name.includes('Grandchild'));
console.log(allResults); // 输出包含所有Grandchild节点的数组
function filterTree(tree, condition) {
// 如果节点本身符合条件,直接返回整个子树
if (condition(tree)) {
return tree;
}
// 否则处理子节点
if (tree.children && tree.children.length) {
const filteredChildren = tree.children
.map(child => filterTree(child, condition))
.filter(child => child !== null);
if (filteredChildren.length) {
return {
...tree,
children: filteredChildren
};
}
}
return null;
}
// 使用示例
const filteredTree = filterTree(tree, node => node.id === 5 || node.id === 1);
console.log(filteredTree);
function findPath(tree, condition, path = []) {
path = [...path, tree];
if (condition(tree)) {
return path;
}
if (tree.children && tree.children.length) {
for (let child of tree.children) {
const result = findPath(child, condition, path);
if (result) {
return result;
}
}
}
return null;
}
// 使用示例
const path = findPath(tree, node => node.id === 5);
console.log(path); // 输出从根节点到目标节点的路径数组
const reduceTree = (tree, condition, reducer, accumulator) => {
accumulator = reducer(accumulator, tree, condition(tree));
if (tree.children && tree.children.length) {
accumulator = tree.children.reduce(
(acc, child) => reduceTree(child, condition, reducer, acc),
accumulator
);
}
return accumulator;
};
// 使用示例:收集所有符合条件的节点
const allMatches = reduceTree(
tree,
node => node.id > 2,
(acc, node, isMatch) => isMatch ? [...acc, node] : acc,
[]
);
console.log(allMatches);
以上方法可以根据实际需求进行调整和组合使用。