JavaScript遍历两数组匹配键值并删除对应对象的实现方法
JavaScript数组匹配删除元素实现
初始场景
现有两个数组:
array1 = [{firstname: 'abc', age: 24}]; array2 = [{name: 'bcg', age: 33}, {name:'abc', age: 55}];
需求为删除array2中name属性值和array1内对象firstname值匹配的元素,示例中需要删除的是array2[1]。
原有实现代码无法正常生效,原代码如下:
for (let p = 0; p < array1.length; p++) { for (let i = 0; i < array2.length; i++) { if (array1[p].firstname === array2[i].name) { array2.splice(i,1); } } }
失效原因
原代码的问题出在splice删除数组元素的特性上:当你通过splice(i,1)删除索引为i的元素时,数组长度会立刻减1,i之后所有元素的索引都会向前偏移1位。但此时循环变量i依旧会按原逻辑自增,会直接跳过被删位置的下一个元素,当存在连续匹配项时就会出现漏删。
正确实现
方法1:修复原循环逻辑(倒序遍历)
把内层循环改成从数组末尾向前遍历,此时删除当前索引的元素不会影响还未遍历到的前序元素的索引,不会出现漏判:
for (let p = 0; p < array1.length; p++) { for (let i = array2.length - 1; i >= 0; i--) { if (array1[p].firstname === array2[i].name) { array2.splice(i, 1); } } }
方法2:filter过滤(推荐写法)
不需要手动维护遍历索引,直接通过数组filter方法筛掉不符合要求的元素,代码可读性更高,也不会出现索引错乱问题。如果array1长度较大,可以先用Set存储匹配值提升查找效率:
// 提取所有需要匹配的firstname const matchSet = new Set(array1.map(item => item.firstname)); // 过滤array2,保留name不在匹配集合中的元素 array2 = array2.filter(item => !matchSet.has(item.name));
如果仅需要匹配array1第一个对象的firstname,可以进一步简化:
array2 = array2.filter(item => item.name !== array1[0].firstname);
两种方法执行后,array2的结果均为[{name: 'bcg', age: 33}],符合需求。
内容的提问来源于stack exchange,提问作者Deji James
相关产品推荐
相关产品推荐

