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

React模态框中实现匹配查询字符串的对象精确路径保留

解决嵌套列表搜索后保留精确路径的问题

你的现有代码仅能筛选出包含匹配项的父节点,但不会修改节点的subItems属性,导致返回的父节点仍携带完整的子列表,而非仅保留到匹配项的路径。要实现预期效果,需要递归处理每个节点时,不仅判断是否保留当前节点,还要替换其subItems为过滤后的子路径。

以下是修改后的实现代码:

type Option = {
  label: string;
  value: string;
  subItems?: Option[];
};

const filterItems = (options: Option[], query: string): Option[] => {
  const lowerQuery = query.toLowerCase();
  return options.reduce((result, option) => {
    // 判断当前项是否匹配查询
    const isCurrentMatch = option.label.toLowerCase().includes(lowerQuery);
    // 递归过滤子项(如果存在)
    const filteredSubItems = option.subItems ? filterItems(option.subItems, lowerQuery) : [];

    // 当前项匹配,或存在匹配的子项时,保留该节点
    if (isCurrentMatch || filteredSubItems.length > 0) {
      result.push({
        ...option,
        // 替换subItems为过滤后的结果(仅当原节点有subItems时)
        ...(option.subItems && { subItems: filteredSubItems })
      });
    }
    return result;
  }, [] as Option[]);
};

const filteredItems = useMemo(() => {
  return filterItems(options, query);
}, [options, query]);

代码逻辑说明

  1. 统一大小写处理:先将查询字符串转为小写,避免重复转换,提升效率。
  2. 递归处理子项:对每个节点的subItems递归调用过滤函数,得到仅包含匹配路径的子列表。
  3. 节点保留规则:如果当前节点自身匹配查询,或者其过滤后的子列表不为空,则保留该节点。
  4. 结构重构:保留原节点的label和value,将subItems替换为过滤后的结果,确保返回的结构仅包含匹配项的完整路径。

测试验证

当查询字符串为Nested baz 2时,函数会逐层递归筛选:

  • 顶层仅Foo节点的子项存在匹配,因此保留Foo;
  • Foo的子项中仅Sub bar 1的子项存在匹配,因此保留Sub bar 1并替换其subItems为仅包含Nested baz 2的数组;
  • 最终返回的结构与你期望的输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:43:22