JS对比两数组按条件push元素时重复插入数据问题如何解决
过滤已存在邮箱数据时出现重复推送的问题修复
问题现象
尝试过滤掉已存在于userData中的emails数据时,代码只要遇到email不匹配的情况就会反复推送同一条数据。
预期仅将email为Johnny_Bravo@sample.com和Jayson.Abuela@mail.com的用户数据推入newData数组,且每条数据仅推入一次,实际运行时这两条数据各自被重复推入多次。
原有问题代码
userData:[ {email: "jane.doe@mail.com", first_name: "Jane", last_name: "Doe"}, {email: "john.doe@sample.com", first_name: "john", last_name: "doe"}, {email: "mary_jane@mail.com", first_name: "Mary", last_name: "Jane"} ], parseData:[ {email: "jane.doe@mail.com", first_name: "Jane", last_name: "Doe"}, {email: "Johnny_Bravo@sample.com", first_name: "Johnny", last_name: "Bravo"}, {email: "Jayson.Abuela@mail.com", first_name: "Jayson", last_name: "Abuela"} ], newData: [] var userData = this.userData var parsedData = this.parseData function(results) { const parsedData = results.data for(var j = 0; j < parsedData.length; j++){ userData.map((data)=>{ if(data.email.toLowerCase() != parseData[j].email.toLowerCase()){ newData.push(parsedData[j]) }else{ alert("This "+parsedData[j].email+" already exist.") } }) } }
问题原因
- 逻辑位置错误:采用双层遍历结构时,把push操作放在了内层
userData的遍历循环里,只要当前遍历到的单个userData项邮箱和待校验项不匹配就会执行push,而不是等遍历完所有userData确认无重复后再push。例如userData共3条数据,待校验的新邮箱和这3条都不匹配,就会被重复push3次。 - 变量命名混乱:代码中混用
parseData和parsedData两个相似变量名,容易引发引用错误。 - 方法使用不当:
Array.map的设计用途是遍历数组并返回由遍历结果组成的新数组,此处仅需做存在性判断,不需要使用map方法。
修正代码
推荐用Set存储已存在的邮箱做去重判断,时间复杂度更低,代码更简洁:
// 提前收集所有已存在的邮箱(统一转小写避免大小写差异导致判断失效) const existingEmailSet = new Set(this.userData.map(item => item.email.toLowerCase())); const newData = []; const parseData = this.parseData; parseData.forEach(item => { const itemEmail = item.email.toLowerCase(); if (existingEmailSet.has(itemEmail)) { alert(`This ${item.email} already exist.`); } else { newData.push(item); // 可选:如果希望新加入的邮箱后续也判定为已存在,就把它加入Set existingEmailSet.add(itemEmail); } });
如果希望保留原有的双层循环写法,只需要调整判断逻辑,把push操作移到内层循环外即可:
const userData = this.userData; const parseData = this.parseData; const newData = []; for (let j = 0; j < parseData.length; j++) { const currentItem = parseData[j]; let isEmailExisted = false; // 遍历已有用户数据判断是否重复 for (let i = 0; i < userData.length; i++) { if (userData[i].email.toLowerCase() === currentItem.email.toLowerCase()) { isEmailExisted = true; break; // 找到重复项直接终止内层循环,减少不必要的遍历 } } if (isEmailExisted) { alert(`This ${currentItem.email} already exist.`); } else { newData.push(currentItem); } }
内容的提问来源于stack exchange,提问作者Three_L_Some
相关产品推荐
相关产品推荐

