You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现含指定关键词的层级菜单对象全路径搜索?

实现层级菜单标题搜索并返回完整路径

需求说明

给定如下层级结构的MenuPath类型数组:

interface MenuPath {
  title: string;
  path: string;
  children?: MenuPath[];
}

let items: MenuPath[] = [
            { title: "Archive", path: 'archive' },
            { title: "About", path: 'about' },
            { title: "Programs", path: 'programs', children: [{ title: 'Line with...', path: 'program-line' }] },
            {
                title: "Blog",
                path: 'blog',
                children: [
                    {
                        title: "Cars",
                        path: 'cars',
                        children: [
                            { title: 'Something about cars', path: 'smt-cars' },
                            {
                                title: 'Cars library',
                                path: 'cars-library',
                                children:  [
                                            { title: 'Line of horizon', path: 'line-horizon', children: [{ title: 'Something', path: 'smt-last' }] },
                                            { title: 'Lineup', path: 'lineup' },
                                        ]
                            }
                        ]
                    }
                ]
            }
        ];

需要实现searchAll函数,查找所有**title包含"line"(不区分大小写)**的对象,并返回每个对象对应的完整父层级路径数组,期望输出如下:

let result = [
   [ {title: "Programs", path: "programs"}, {title: "Line with...", path: 'program-line'} ], // path: /programs/program-line
   [ {title: "Blog", path: "blog"}, { title: "Cars", path: "cars" }, {title:"Cars library", path: "cars-library"}, {title: 'Line of horizon', path: 'line-horizon'} ], // path: /blog/cars/cars-library/line-horizon
   [ {title: "Blog", path: "blog"}, { title: "Cars", path: "cars" }, {title:"Cars library", path: "cars-library"}, {title: 'Lineup', path: 'lineup'} ], // path: /blog/cars/cars-library/lineup
];

实现方案

思路

采用**深度优先遍历(DFS)**递归遍历菜单树,全程维护当前节点的层级路径:

  • 遍历每个节点时,将节点加入当前路径
  • 检查节点标题是否匹配关键词,匹配则将当前路径的副本存入结果
  • 若节点有子节点,递归遍历子节点并传递更新后的路径
  • 遍历完子节点后自动完成回溯,避免路径污染

代码实现

interface MenuPath {
  title: string;
  path: string;
  children?: MenuPath[];
}

function searchAll(items: MenuPath[], keyword: string): MenuPath[][] {
  const result: MenuPath[][] = [];

  const traverse = (nodes: MenuPath[], currentPath: MenuPath[]) => {
    for (const node of nodes) {
      // 创建路径副本,避免引用类型修改影响已存入结果的路径
      const updatedPath = [...currentPath, { ...node }];

      // 不区分大小写匹配关键词
      if (node.title.toLowerCase().includes(keyword.toLowerCase())) {
        result.push(updatedPath);
      }

      // 递归处理子节点
      if (node.children?.length) {
        traverse(node.children, updatedPath);
      }
    }
  };

  traverse(items, []);
  return result;
}

// 调用示例
const items: MenuPath[] = [
  { title: "Archive", path: 'archive' },
  { title: "About", path: 'about' },
  { title: "Programs", path: 'programs', children: [{ title: 'Line with...', path: 'program-line' }] },
  {
    title: "Blog",
    path: 'blog',
    children: [
      {
        title: "Cars",
        path: 'cars',
        children: [
          { title: 'Something about cars', path: 'smt-cars' },
          {
            title: 'Cars library',
            path: 'cars-library',
            children: [
              { title: 'Line of horizon', path: 'line-horizon', children: [{ title: 'Something', path: 'smt-last' }] },
              { title: 'Lineup', path: 'lineup' },
            ]
          }
        ]
      }
    ]
  }
];

const result = searchAll(items, 'line');
console.log(result);

代码说明

  • 定义MenuPath接口确保类型安全,避免隐式类型错误
  • 使用数组展开创建路径副本,防止后续操作修改已存入结果的路径数据
  • 统一转为小写实现不区分大小写的关键词匹配,提升搜索兼容性
  • 递归遍历子节点时传递更新后的路径,确保层级路径的准确性

内容的提问来源于stack exchange,提问作者AlT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 10:55:57