我希望删除数组中的所有匹配项,我有一个函数,我发送一个值,并通过数组中的所有匹配项,如果存在,我删除,但每个splice
的数组更改,请看这个是一个小例子
var cars = ["Saab","Saab","Saab", "Volvo", "BMW","Volvo","Volvo", "BMW", "BMW", "BMW","Volvo"];
for(j =0;j<cars.length;j++){
if(cars[j]=="Volvo"){
cars.splice(j, 1);
}
}
console.log(cars);
结果
["Saab", "Saab", "Saab", "BMW", "Volvo", "BMW", "BMW", "BMW"]
答案 0 :(得分:4)
因为索引在从数组的开头到结尾循环并删除元素时可能会搞乱,所以通常最好向后:
var i = cars.length - 1;
while(i >= 0) {
if(/* condition */) {
cars.splice(i, 1);
}
i--;
}
我讨厌原生循环(没有充分的理由,只是个人偏好),所以我更喜欢使用语义forEach/reduce/map/filter
。
filter
实际上是最具语义的(下一个,可能是reduce
):
var filteredCars = cars.filter(notVolvo);
function notVolvo(car) {
return car !== 'Volvo';
}
如果对于踢腿和咯咯笑,你想使用reduce
,你可以这样做:
var reducedCars = cars.reduce(notVolvo, []);
function notVolvo(aggregate, car) {
return car === 'Volvo' ? aggregate : aggregate.concat([car]);
}
答案 1 :(得分:0)
问题在于,当您使用splice
删除项目时,以下项目将向后移动一个位置,以便没有间隙。
但是,您的循环会根据项目是否被删除而独立增加索引变量。这意味着,当您删除某个项目时,将跳过下一个项目。
这可以通过用减量来抵消增量来解决:
for (var i=0; i<cars.length; i++)
if (cars[i] == "Volvo")
cars.splice(i--, 1);