嵌套数组对象过滤问题:需精准返回匹配子项而非完整子数组
问题:实现分类与通讯稿的精准搜索过滤
原始数据结构
{ categories: [ { "category": { "categoryName": "categoryName1" }, "newsletter": [ { "name": "AAA", "description": "111" }, { "name": "BBB", "description": "222" }, { "name": "CCC", "description": "333" } ] }, { "category": { "categoryName": "categoryName2" }, "newsletter": [ { "name": "DDD", "description": "444" }, { "name": "EEE", "description": "555" } ] } ] }
现有逻辑及问题
当前过滤代码如下:
this.selectedCategoryData = this.categorisedData.filter((item) => { const categoryMatch = item.category.categoryName.toLowerCase().includes(filterValueLowercase); const newslettersMatch = item.newsletters.some(newsletter => return newsletter.name.toLowerCase().includes(filterValueLowercase) || newsletter.description.toLowerCase().includes(filterValueLowercase); ); return categoryMatch || newslettersMatch; });
问题:匹配到newsletter子数组内容时,会返回整个子数组而非仅匹配的子项。需实现两种效果:
- 场景一:搜索值为"AAA"时,返回包含该通讯稿的分类,且仅保留匹配的通讯稿项
- 场景二:搜索值为"categoryName1"时,返回该分类及其下所有通讯稿
解决方案
修改逻辑,先筛选符合条件的分类,再针对性处理每个分类的newsletter数组:
const filterValueLowercase = /* 你的搜索值转小写 */; this.selectedCategoryData = this.categorisedData .map(item => { const categoryMatch = item.category.categoryName.toLowerCase().includes(filterValueLowercase); // 筛选当前分类下匹配的通讯稿 const matchedNewsletters = item.newsletter.filter(newsletter => newsletter.name.toLowerCase().includes(filterValueLowercase) || newsletter.description.toLowerCase().includes(filterValueLowercase) ); // 根据匹配情况生成结果对象 if (categoryMatch) { // 分类匹配时保留全部通讯稿 return { ...item }; } else if (matchedNewsletters.length > 0) { // 仅通讯稿匹配时,返回分类+匹配的通讯稿 return { ...item, newsletter: matchedNewsletters }; } // 无匹配则标记为null,后续过滤 return null; }) // 过滤掉无匹配的分类项 .filter(item => item !== null);
逻辑说明
- 用
map遍历每个分类项,单独处理:- 判断分类名是否匹配搜索值
- 筛选当前分类下符合条件的通讯稿列表
- 根据匹配结果生成新对象:
- 分类名匹配:直接返回原分类对象(保留所有通讯稿)
- 仅通讯稿匹配:返回包含匹配通讯稿的新对象
- 无匹配:返回
null
- 最后用
filter移除所有null项,得到最终结果
内容的提问来源于stack exchange,提问作者Nikunj Chaklasiya
相关产品推荐
相关产品推荐

