简体   繁体   English

为什么我必须在从我的数组中提取之前从我的参数中提取以从数组中删除一个项目?

[英]Why do I have to pull from my argument before pulling from my array wrt to removing an item from an array?

Here's the code I'm working with:这是我正在使用的代码:

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;
}

I can get the code to work if I switch the outer loop with the inner loop.如果我用内循环切换外循环,我可以让代码工作。

I just can't figure out logically why it doesn't work if my outer loop pulls from the parameter array first.如果我的外循环首先从参数数组中提取,我只是无法从逻辑上弄清楚为什么它不起作用。 It works for most things, but it has problems with this for example:它适用于大多数事情,但它有以下问题,例如:

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

It only removes 2 leaving 3 untouched.它只删除 2 个,留下 3 个不变。

I thought maybe the loop removes the 2 and pushes 3 down the index.我想也许循环会删除 2 并将 3 推下索引。 But in that case, removeFromArray([1,2,3,4], 1, 2, 3, 4) wouldn't work but it does.但在这种情况下, removeFromArray([1,2,3,4], 1, 2, 3, 4) 不起作用,但它起作用了。

What am I not getting?我没有得到什么?

splice will mutate the array. splice会改变数组。 If you're iterating over the array at the same time you splice , you'll have to be careful to reset the index back to account for the newly rearranged elements.如果您在splice的同时迭代数组,则必须小心地将索引重置回以考虑新重新排列的元素。 For example, with [1, 2, 3, 4] , if both 2 and 3 match the condition to remove element from the array:例如,对于[1, 2, 3, 4] ,如果 2 和 3 都匹配从数组中删除元素的条件:

  • On one iteration, x will be 1, matching value 2. 2 will be removed from the array with splice .在一次迭代中, x将为 1,匹配值 2。2 将从带有splice的数组中删除。 The array will then become [1, 3, 4] .然后数组将变为[1, 3, 4]
  • If, at this point, you increment x , it'll then be 2, so the item at index 2 will be checked.如果此时您增加x ,那么它将是 2,因此将检查索引 2 处的项目。 But the item at that index is now 4;但是该索引处的项目现在是 4; the 3 is never checked. 3 永远不会被检查。 Or, if you increment y , the index of the argument being checked, then the argument that was just removed won't be checked again.或者,如果您增加y ,即正在检查的参数的索引,则不会再次检查刚刚删除的参数。

Either manually decrement the index when a match is found找到匹配项时手动递减索引

 // 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));

or use .filter instead:或使用.filter代替:

 const removeFromArray = (arr, ...toRemove) => arr.filter( item => !toRemove.includes(item) ); console.log(removeFromArray([1,2,3,4], 3, 2));

Also make sure to use the same capitalization - if you define the function as removeFromArray , make sure to call it with a capital F .还要确保使用相同的大写 - 如果您将函数定义为removeFromArray ,请确保使用大写F调用它。 (using removefromArray instead will throw a ReferenceError) (改用removefromArray会抛出一个 ReferenceError)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM