本文介绍一种基于递归与栈结构的深度优先搜索方法,用于在具有层级关系的嵌套对象数组(如菜单树)中,精准定位所有 title 包含指定关键词(如 "line")的节点,并返回其从根到匹配项的完整路径数组。
本文介绍一种基于递归与栈结构的深度优先搜索方法,用于在具有层级关系的嵌套对象数组(如菜单树)中,精准定位所有 `title` 包含指定关键词(如 "line")的节点,并返回其从根到匹配项的完整路径数组。
在构建导航菜单、权限路由或内容目录等场景中,数据常以树形结构组织——每个节点可能包含 children 数组,形成多层嵌套。当需要根据标题模糊查找所有匹配项并保留其完整层级路径时,简单的扁平化遍历无法满足需求;必须同步维护“当前路径上下文”。
核心思路是:使用调用栈(显式 stack 数组)动态记录从根节点到当前遍历节点的路径,并在每次进入子节点前压入该节点,在回溯前弹出,确保路径状态始终准确。配合正则表达式匹配,可灵活支持大小写不敏感、前缀/子串等搜索逻辑。
以下是完整实现:
function searchAll<T extends { title: string; path: string; children?: T[] }>( items: T[], search: RegExp): T[][] { const stack: T[] = []; const results: T[][] = []; function traverse(nodes: T[]): void { for (const node of nodes) { // 将当前节点加入路径栈 stack.push(node); // 若标题匹配,保存当前完整路径(深拷贝避免引用污染) if (search.test(node.title)) { results.push(structuredClone(stack)); } // 递归处理子节点 if (Array.isArray(node.children) && node.children.length > 0) { traverse(node.children); } // 回溯:退出当前节点,恢复上一层路径状态 stack.pop(); } } traverse(items); return results;}
✅ 使用示例:
const result = searchAll(items, /line/i);console.log(result);// 输出三个路径数组,分别对应:// /programs/program-line// /blog/cars/cars-library/line-horizon// /blog/cars/cars-library/lineup
⚠️ 注意事项:
此方案简洁、可读性强,且天然支持任意深度嵌套,是处理树形数据层级搜索的通用范式。