如何实现含指定关键词的层级菜单对象全路径搜索?
实现层级菜单标题搜索并返回完整路径
需求说明
给定如下层级结构的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
相关产品推荐
相关产品推荐

