从freeCodeCamp处理挑战,我必须创建一个接受array
和其他一些参数的函数。如果传递的数组中的元素与传递的参数之一匹配,则必须从数组中删除它。
我已编写此代码,但它并不适用于所有测试:
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments);
for(i=0; i<arr.length; i++){
for(var j=0; j<args.length; j++){
if(args[j]===arr[i]){
arr.splice(i,1);
}
}
}
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
步骤1:将参数对象转换为数组,因此我可以将其视为一个。
步骤2:运行嵌套for循环以查找传递的数组和传递的参数数组之间的任何匹配项。
第3步:如果找到匹配项,请使用.splice(i,1)
将其删除。
不应该这样做吗?我究竟做错了什么?
编辑:这是失败的测试示例:
destroyer([3, 5, 1, 2, 2], 2, 3, 5)
应该返回[1]
。
答案 0 :(得分:4)
您正在迭代它时更改数组。因此,在第一个splice
指数发生变化之后。
您可以使用filter
和indexOf
来执行此操作。
function destroyer(array) {
var toRemove = [].slice.call(arguments, 1);
return array.filter(function(item) {
return toRemove.indexOf(item) === -1
})
}
console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5))
如果您仍想使用for循环。但请记住splice
变异数组。所以你的函数确实会改变通常应该避免的参数。
function destroyer(arr) {
var args = Array.prototype.slice.call(arguments);
for(var i=0; i<arr.length; i++){
for(var j=1; j<args.length; j++){
if(args[j]===arr[i]){
arr.splice(i,1);
i--; // manually reduce index
}
}
}
return arr;
}
console.log(destroyer([1, 2, 3, 1, 2, 3], 2, 3));
console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5));
答案 1 :(得分:1)
问题在于,每次从arr
中删除项目时,您的循环都会跳过下一项。想象一下,你正在迭代以下数组:
['a', 'b', 'c', 'd', 'e']
假设您处于迭代2
,对应于数组中的'c'
项,并删除该项。你的数组现在看起来像这样:
['a', 'b', 'd', 'e']
现在'd'
将对应当前的迭代2
,但您的for
lopp将继续下一次迭代,3
和'd'
项将永远不会被处理。
由于数组正在被修改,我建议改为使用while
循环:
var i = 0;
while (i < arr.length){
for(var j=0; j<args.length; j++){
if(args[j]===arr[i]){
arr.splice(i,1);
} else {
i++;
}
}
}
此处,如果您删除了该项,则i
不会增加,因为这意味着下一个项目已移至当前位置i