JavaScript数组筛选与去重问题:如何获取含指定关键词且无重复caption的对象
问题排查与正确实现方案
咱们先一步步拆解你当前代码里的问题,再给出符合需求的正确实现方案:
原代码的核心问题
forEach无法赋值结果:forEach是用来遍历执行副作用的,它本身不会返回任何值(默认返回undefined),所以当keywordsToBeSearched有内容时,linkData会被赋值成undefined,这直接导致结果为空。- 未处理多关键词匹配的重复项:如果某个link的caption同时匹配多个关键词,会被多次筛选出来,最终结果会出现重复的对象。
- 空关键词场景未做去重:需求明确要求空关键词时要过滤掉相同caption的重复对象,但原代码只筛选了
images非空的项,完全没处理去重逻辑。
正确实现方案
我们可以分两种场景处理,同时封装通用的去重逻辑来满足需求:
let linkData = []; const { keywordsToBeSearched, links } = this; // 通用去重函数:根据caption去重,保留第一个出现的对象(不区分大小写) const deduplicateByCaption = (arr) => { const seenCaptions = new Set(); return arr.filter(item => { const lowerCaption = item.caption.toLowerCase(); if (!seenCaptions.has(lowerCaption)) { seenCaptions.add(lowerCaption); return true; } return false; }); }; if (keywordsToBeSearched.length > 0) { // 1. 先筛选出所有images非空的link,缩小后续处理范围 const validLinksWithImages = links.filter(link => link.images.length !== 0); // 2. 筛选caption包含任一关键词的link(不区分大小写) const matchedLinks = validLinksWithImages.filter(link => { const lowerCaption = link.caption.toLowerCase(); return keywordsToBeSearched.some(keyword => lowerCaption.includes(keyword.toLowerCase()) ); }); // 3. 去重,避免同一个link匹配多个关键词导致重复 linkData = deduplicateByCaption(matchedLinks); } else { // 空关键词场景:先筛选images非空,再按caption去重 const validLinksWithImages = links.filter(link => link.images.length !== 0); linkData = deduplicateByCaption(validLinksWithImages); } console.log(linkData); return linkData;
代码细节解释
- 通用去重函数:
deduplicateByCaption用Set记录已经出现过的小写caption,确保每个caption只保留第一个出现的对象,完美匹配需求里的去重要求。 - 关键词存在场景:
- 先过滤出
images非空的link,减少后续筛选的数据集,提升性能; - 用
some方法判断当前link的caption是否包含任一关键词(统一转小写实现不区分大小写匹配); - 最后对匹配结果去重,避免重复项。
- 先过滤出
- 空关键词场景:直接筛选
images非空的link,再用去重函数处理重复caption的问题。
测试结果(针对你提供的links数组)
当keywordsToBeSearched = ['house', 'carver', 'hello']时,最终linkData会包含以下两个符合预期的对象:
[ { "url": "https://en.wikipedia.org/wiki/Raymond_Carver", "images": [ { "url": "https://upload.wikimedia.org/wikipedia/commons/c/cc/Raymond_Carver.jpg" } ], "caption": "Carver", "suggestionId": "89475630-d03d-47a3-8970-e4251af91afe", "offsetMillis": [ 19600, 69300 ] }, { "url": "https://en.wikipedia.org/wiki/House", "images": [ { "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/49/103_Hanover.jpg/1200px-103_Hanover.jpg" } ], "caption": "House", "suggestionId": "38d31cc2-ce0e-4927-8b47-a99cabe58663", "offsetMillis": [ 75600 ] } ]
内容的提问来源于stack exchange,提问作者vini
相关产品推荐
相关产品推荐

