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' } ] } ] } ];
问题分析
当前代码存在两个核心问题:
- 仅处理菜品名称匹配,未实现分类名称的匹配逻辑;
- 每匹配到一个菜品就将外层分类对象推入数组,导致同一分类因多个匹配菜品被重复添加。
原问题代码:
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
相关产品推荐
相关产品推荐

