为什么forEach arr.splice不能删除掉所有匹配上的元素?
let arr = [1,2,3,3,5]
arr.forEach((item, index) => {
if (item === 3) {
arr.splice(index, 1)
}
})
console.log(arr) // [ 1, 2, 3, 5 ]
为什么forEach arr.splice不能删除掉所有匹配上的元素?
let arr = [1,2,3,3,5]
arr.forEach((item, index) => {
if (item === 3) {
arr.splice(index, 1)
}
})
console.log(arr) // [ 1, 2, 3, 5 ]
这样破坏性的循环就算处理了也是有隐患和不利于理解的。
分析一下:
数组有五个元素
从循环次数分析,大概只循环走了4次,分别经过和对应:
0 1
1 2
2 3
这里少了一次,因为index=2的时候删掉了,原来index=3的3变成了index=2
3 5
换一个写法比较靠谱
1
let arr = [1,2,3,3,5]
let res = []
arr.forEach((item, index) => {
if (item !== 3) {
//arr.splice(index, 1)
res.push(item)
}
})
// console.log(arr) // [ 1, 2, 3, 5 ]
console.log(res) // [1, 2, 5]
2
let arr = [1,2,3,3,5]
let res = arr.filter(item=>item !== 3)
// console.log(arr) // [ 1, 2, 3, 5 ]
console.log(res) // [1, 2, 5]
splice方法是会改变原数组的,也就是,你使用splice删除一个元素之后,下一次循环的index依然加了一,但是数组少了刚刚删除的那个元素,
就你的代码而言,第一次匹配正确的index是2,下一个循环index加了1是3,但是现在的arr == [1,2,3,5],所以item是5,未匹配上,自然就不会再执行splice
8 回答5.8k 阅读✓ 已解决
9 回答9.2k 阅读
6 回答4.8k 阅读✓ 已解决
5 回答3.5k 阅读✓ 已解决
4 回答7.9k 阅读✓ 已解决
7 回答9.8k 阅读
5 回答7.1k 阅读✓ 已解决
就OP你的这个需求为什么不用
filter
,而去使用forEach
+splice
呢?如果非要使用
splice
的话,应该是从后往前操作。因为你
splice
删除掉其中一项之后,数组的下标就变更了,所以会跳过第二个3
。改成这样就可以了。