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

JavaScript嵌套过滤搜索结果去重问题求助

解决搜索结果重复问题

需求说明

当搜索输入匹配categories.name或categories -> dishes -> dish.name时,输出对应的categories.name(注:若需返回外层分类对象可按代码逻辑调整)。

提供的JS数据结构如下:

[
  {
    name: 'Tikka',
    img: 'paneer malai tikka.jpg',
    categories: [
      {
        isActive: true,
        isDeleted: false,
        _id: '61a22648521aa07d718745b6',
        name: 'Tikka',
        dishes: [
          {
            isActive: true,
            isDeleted: false,
            _id: '61a22648521aa07d718745b7',
            name: 'paneer malai tikka',
            img: 'paneer malai tikka.jpg',
            type: 'veg'
          },
          {
            isActive: true,
            isDeleted: false,
            _id: '61a22648521aa07d718745b9',
            name: 'panner jaitoni tikka',
            img: 'jaitooni paneer tikka.png',
            type: 'veg'
          },
          {
            isActive: true,
            isDeleted: false,
            _id: '61a22648521aa07d718745bb',
            name: 'chicken pahadi tikka',
            img: 'chicken pahadi tikka.jpeg',
            type: 'non veg'
          }
        ]
      },
      {
        isActive: true,
        isDeleted: false,
        _id: '61a22648521aa07d718745f2',
        name: 'Tikka',
        dishes: [
          {
            isActive: true,
            isDeleted: false,
            _id: '61a22648521aa07d718745f3',
            name: 'lehsuni fish tikka',
            img: 'lehsuni fish tikka.jpg',
            type: 'non veg'
          }
        ]
      }
    ]
  }
];

问题分析

当前代码存在两个核心问题:

  1. 仅处理菜品名称匹配,未实现分类名称的匹配逻辑;
  2. 每匹配到一个菜品就将外层分类对象推入数组,导致同一分类因多个匹配菜品被重复添加。

原问题代码:

let filteredData = [];
categories.forEach((category) =>
  category.categories.forEach((subcategory) =>
    subcategory.dishes.forEach(dish => {
      if (dish.name.toLowerCase().includes(searchInput)) {
        filteredData.push(category);
      };
    })
  )
)

解决方案

方案1:数组判断去重

遍历过程中检查分类是否已存在于结果数组,仅添加一次:

let filteredData = [];
// 统一转换搜索词为小写,避免大小写敏感
const lowerSearchInput = searchInput.toLowerCase();

categories.forEach((category) => {
  // 检查当前分类下是否有符合条件的子分类
  const hasMatch = category.categories.some(subcategory => {
    // 匹配子分类名称
    const matchesCategory = subcategory.name.toLowerCase().includes(lowerSearchInput);
    // 匹配子分类下的菜品
    const matchesDish = subcategory.dishes.some(dish => dish.name.toLowerCase().includes(lowerSearchInput));
    return matchesCategory || matchesDish;
  });

  if (hasMatch && !filteredData.includes(category)) {
    filteredData.push(category);
  }
});

方案2:利用Set自动去重

Set会自动存储唯一的对象引用,最后转换为数组:

const filteredSet = new Set();
const lowerSearchInput = searchInput.toLowerCase();

categories.forEach((category) => {
  const hasMatch = category.categories.some(subcategory => {
    const matchesCategory = subcategory.name.toLowerCase().includes(lowerSearchInput);
    const matchesDish = subcategory.dishes.some(dish => dish.name.toLowerCase().includes(lowerSearchInput));
    return matchesCategory || matchesDish;
  });

  if (hasMatch) {
    filteredSet.add(category);
  }
});

const filteredData = Array.from(filteredSet);

补充:若需仅返回去重后的categories.name

如果最终需求是仅输出匹配的分类名称,可调整代码如下:

const categoryNames = new Set();
const lowerSearchInput = searchInput.toLowerCase();

categories.forEach((category) => {
  category.categories.forEach(subcategory => {
    const matchesCategory = subcategory.name.toLowerCase().includes(lowerSearchInput);
    const matchesDish = subcategory.dishes.some(dish => dish.name.toLowerCase().includes(lowerSearchInput));
    
    if (matchesCategory || matchesDish) {
      categoryNames.add(subcategory.name);
    }
  });
});

// 转换为数组输出
const result = Array.from(categoryNames);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:15:41