while循环中splice删除数组元素不彻底的原因及参数差异疑问
数组删除'b'元素残留问题解析
嘿,我来帮你拆解这个问题,这是数组遍历删除元素时很容易踩的坑!
一、为什么删除后还残留'b'?
咱们先看你的循环逻辑:
let array = ['a','b','c','b','d','e','d','b','b','b','d','d']; var i = 0; while (i < array.length){ if (array[i] === 'b'){ array.splice(i,1); } i++; }
当你用splice(i,1)删除第i位的元素时,数组中i位置后面的所有元素都会往前移动一位。举个具体的例子:假设当前i=7,元素是'b',删除后原来i=8的'b'会移到i=7的位置,但紧接着你执行了i++,i变成8,这就直接跳过了现在在i=7的那个'b',导致它没被检查到,最后留在数组里。
比如拿更简单的测试用例['b','b']来说:
- 第一次循环i=0,删除后数组变成
['b'],然后i++变成1; - 此时
array.length是1,i < array.length(1<1)不成立,循环结束,剩下的那个'b'就没被处理。
这就是残留'b'的核心原因:删除元素后没有调整i的位置,导致跳过了前移过来的元素。
二、为什么splice传第三个参数替换时功能正常?
当你用splice(i,1, '其他元素')的时候,这个操作是删除1个元素,同时在该位置插入1个元素,数组的总长度没有变化。这时候,i位置后面的元素不会往前移动,你执行i++后,下一次循环会正常检查下一个位置的元素,所有的'b'都能被遍历到并替换,所以功能完全正常。
附:彻底删除所有'b'的修复方案
如果要彻底删除所有'b',你只需要在删除元素后,不让i递增(或者说把i减1),这样下一次循环会重新检查当前i位置(因为后面的元素已经移过来了):
let array = ['a','b','c','b','d','e','d','b','b','b','d','d']; var i = 0; while (i < array.length){ if (array[i] === 'b'){ array.splice(i,1); } else { // 只有当没删除元素的时候,才递增i i++; } } console.log(array); // 输出:['a','c','d','e','d','d','d']
或者更简洁且推荐的方式,用filter方法——它会返回一个新数组,包含所有符合条件的元素,完全避免了遍历原数组修改时的索引问题,代码也更清晰:
const array = ['a','b','c','b','d','e','d','b','b','b','d','d']; const filteredArray = array.filter(item => item !== 'b'); console.log(filteredArray);
内容的提问来源于stack exchange,提问作者Krzysiek Kowalski
相关产品推荐
相关产品推荐

