为什么在从数组wrt中删除要从数组中删除项目之前,必须从参数中删除?

时间:2020-11-02 04:37:44

标签: javascript arrays loops nested-loops

这是我正在使用的代码:

const removeFromArray = function(arr) {
    let args = Array.from(arguments);
    for(let x=0; x<arr.length; x++) {
        for(let y=1; y<args.length; y++) {
            if(arr[x]===args[y]) {
                arr.splice(x,1);
            }
        }
    }
    return arr;
}

如果我用内循环切换外循环,我的代码就可以工作。

如果我的外循环首先从参数数组中拉出,我只是无法从逻辑上弄清楚为什么它不起作用。它适用于大多数情况,但是存在一些问题,例如:

removefromArray([1,2,3,4],3,2)

它只会删除2个,保留3个不变。

我认为也许循环会删除2并将3推下索引。 但是在那种情况下,removeFromArray([1,2,3,4],1、2、3、4)无效,但是可以。

我没有得到什么?

1 个答案:

答案 0 :(得分:0)

splice将使数组变异。如果您在splice的同时遍历数组,则必须小心地将索引重设回原位,以解决新重新排列的元素。例如,对于[1, 2, 3, 4],如果2和3都符合从数组中删除元素的条件:

  • 在一次迭代中,x将为1,匹配值2。将使用splice从数组中删除2。然后,该数组将变为[1, 3, 4]
  • 如果此时您将x递增,则它将为2,因此将检查索引2处的项目。但是该索引处的项目现在是4; 3永远不会检查。或者,如果您增加y,则要检查的参数的索引,则不会再次检查刚刚删除的参数。

找到匹配项后,手动减少索引

// Not recommended; verbose, ugly, and impure
const removeFromArray = function(arr) {
    let args = Array.from(arguments);
    for(let x=0; x<arr.length; x++) {
        for(let y=1; y<args.length; y++) {
            if(arr[x]===args[y]) {
                arr.splice(x,1);
                x--;
            }
        }
    }
    return arr;
}

console.log(removeFromArray([1,2,3,4], 3, 2));

或改用.filter

const removeFromArray = (arr, ...toRemove) => arr.filter(
  item => !toRemove.includes(item)
);

console.log(removeFromArray([1,2,3,4], 3, 2));

还请确保使用相同的大小写-如果将函数定义为removeFromArray,请确保使用大写字母F进行调用。 (改为使用removefromArray会引发ReferenceError)

相关问题