怎样递归搜索嵌套对象树中匹配标题的全部完整路径

作者:袖梨 2026-06-28

本文介绍一种基于递归与栈结构的深度优先搜索方法,用于在具有层级关系的嵌套对象数组(如菜单树)中,精准定位所有 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

⚠️ 注意事项

  • structuredClone 是现代浏览器及 Node.js 17+ 支持的安全深拷贝方案;若需兼容旧环境,请替换为 JSON.parse(JSON.stringify(stack))(仅适用于纯数据对象,无函数/Date/Map 等);
  • 该算法时间复杂度为 O(n)(n 为总节点数),空间复杂度最坏为 O(h)(h 为树最大深度),符合深度优先搜索特性;
  • search 参数推荐使用 RegExp 而非字符串,便于扩展(如 /^line/i 匹配开头,/blineb/i 匹配单词边界);
  • 若需返回扁平化结果或带路径字符串(如 '/blog/cars/...'),可在 results.push(...) 前自行拼接 stack.map(n => n.path).join('/')。

此方案简洁、可读性强,且天然支持任意深度嵌套,是处理树形数据层级搜索的通用范式。

相关文章

精彩推荐