JavaScript如何单次遍历统计对象数组中匹配指定数组的不重复元素个数
问题原因
- 原代码逻辑是每匹配到一个符合条件的
details元素就计数+1,没有对已经统计过的姓名做去重,所以Aries在details里出现两次就被计数了两次,最终得到3而不是预期的2 - 额外注意:原代码用
eachDetail.Name.includes(el)判断存在有逻辑漏洞,如果details里的姓名是包含目标姓名的更长字符串(比如DevidTest)会被误判,推荐直接用全等判断或者直接判断数组是否包含该元素
修正代码
以下方案仅单次遍历details数组即可得到结果,符合要求:
let names = ['Devid', 'Aries','James']; let details = [ {"Name":"John"}, {"Name":"Devid"}, {"Name":"Aries"}, {"Name":"Aries"} ]; // 用Set存储已经匹配到的姓名,自动去重 const foundNames = new Set(); // 提前把names转成Set,大数组场景下查找效率更高 const nameSet = new Set(names); for (const eachDetail of details) { const currName = eachDetail.Name; if (nameSet.has(currName)) { foundNames.add(currName); } } // Set的size就是去重后的匹配数量 const count = foundNames.size; console.log(count); // 输出2
如果需要兼容低版本环境不使用Set,也可以用普通对象记录已统计的姓名:
let names = ['Devid', 'Aries','James']; let details = [ {"Name":"John"}, {"Name":"Devid"}, {"Name":"Aries"}, {"Name":"Aries"} ]; const foundMap = {}; let count = 0; const nameSet = new Set(names); for (const eachDetail of details) { const currName = eachDetail.Name; if (nameSet.has(currName) && !foundMap[currName]) { foundMap[currName] = true; count++; } } console.log(count); // 输出2
内容的提问来源于stack exchange,提问作者Kainat
相关产品推荐
相关产品推荐

