JavaScript跨JSON数组匹配ani字段,筛选未命中白名单的条目生成新对象
原有代码问题排查
- 遍历方式不匹配:
for...in设计用途是遍历对象的可枚举属性,用来遍历数组时容易混入原型链上的自定义属性,导致遍历到非预期的数组项 - 筛选逻辑完全错误:原代码将白名单作为外层循环,只要报告条目ani和当前遍历到的白名单ani不相等,就直接将报告条目推入结果集,没有对单条报告条目做「是否存在任意白名单ani和其匹配」的全局校验。按给定测试数据运行原代码,最终会生成包含15个重复条目的错误集合,和预期的筛选效果完全不符。
正确实现方案
方案1:使用Set优化匹配效率(推荐)
先将白名单的ani值提取为Set结构,匹配时时间复杂度为O(1),整体处理效率远高于双层嵌套循环:
// 预提取白名单ani集合 const whitelistAniSet = new Set(anis_whitelisted_db.map(item => item.ani)); // 筛选出所有不在白名单中的报告条目 const anis_not_whitelisted = anis_report.filter(reportItem => !whitelistAniSet.has(reportItem.ani) );
示例运行输出(匹配给定测试数据)
[ { ani: '526642111071', Times_repeated: 9, Minutes: '6.00' }, { ani: '524499765316', Times_repeated: 8, Minutes: '31.20' }, { ani: '525517421550', Times_repeated: 7, Minutes: '167.10' } ]
方案2:基础循环实现(无Set依赖场景)
如果需要在不支持Set的旧环境运行,可以用标记位修正原有循环逻辑,避免重复推入错误条目:
const anis_not_whitelisted = []; // 外层遍历每一条报告,单独做白名单匹配 anis_report.forEach(reportItem => { let isInWhitelist = false; // 内层遍历白名单查找匹配项 for (const whitelistItem of anis_whitelisted_db) { if (whitelistItem.ani === reportItem.ani) { isInWhitelist = true; // 匹配成功后提前终止内层循环,减少无意义遍历 break; } } // 遍历完所有白名单仍未匹配,才加入最终结果集 if (!isInWhitelist) { anis_not_whitelisted.push(reportItem); } });
内容的提问来源于stack exchange,提问作者Felipe Carreón
相关产品推荐
相关产品推荐

