JavaScript从数组中删除所有出现的值

9
我正在使用下面的代码片段从数组中删除所有出现的值(在这种情况下是97)。 我无法理解为什么输出数组中会有一个值为97。 当我删除32时,它会从数组中删除所有32。 6也是一样。 为什么这里的97有问题? 对我来说很奇怪。(我想可能是97没有正确输入或者其他原因)。

var inputArr = [3, 97, 32, 6, 97, 2, 9,32, 1, 32, 97, 97, 6, -1, 5];

function removeItem(array, item) {
  for(i = 0; i<array.length; i++){
    if(array[i] == item) {
      array.splice(array.indexOf(item), 1);
    }
  }
}
removeItem(inputArr, 97); removeItem(inputArr, 32); removeItem(inputArr, 6);

document.getElementById("output").innerHTML = inputArr;
<p id="output"></p>


2
在迭代数组时改变它的值通常是一个不好的主意,因为每次你移除某个元素时,数组的长度都会发生变化。 - Yury Tarabanko
Yury Tarabanko。感谢您提供的信息。我会记在心里的。 - Kiran Dash
9个回答

12

问题与兄弟97s相关-1, 32, 97, 97, 6。 当您按此顺序拼接第一个97时,下一个97会更改其索引并进入第一个97,但变量i在跟踪该项之后。

当您删除项目时,通过--i减少索引。

您还可以通过filter函数完成。这将创建一个新数组,您只需要返回它。在这里,我创建了一个带有input数组和过滤input并返回当前对象的函数的对象。这将使您能够级联函数,我认为这是代码风格中的美丽之处,并且可以帮助您处理某些内容。

const obj = {
   input: [3, 97, 32, 6, 97, 2, 9,32, 1, 32, 97, 97, 6, -1, 5],
   removeItem(item) {
      this.input = this.input.filter(i => i !== item);
      return this;
   }
}

const output = obj.removeItem(97)
                  .removeItem(32)
                  .removeItem(6); 
      
console.log(output.input);


感谢您的详细解释。 - Kiran Dash
2
或者简单地说,removeItems = (a, b) => a.filter(x => !b.includes(x)) - georg

9

当您改变数组并在切割时增加索引时,您可以采取另一种方法,从数组的末尾开始。这意味着以下项仍然可用于其原始索引,并且如果需要,可以进行检查和切割,而不会留下未切割的值。

function removeItem(array, item) {
  var i = array.length;

  while (i--) {
    if (array[i] === item) {
      array.splice(i, 1);
    }
  }
}

var inputArr = [3, 97, 32, 6, 97, 2, 9, 32, 1, 32, 97, 97, 6, -1, 5];

removeItem(inputArr, 97);
removeItem(inputArr, 32);
removeItem(inputArr, 6);

console.log(inputArr);


@DylanMaxey,没错,我应该读一下代码。感谢编辑。 - Nina Scholz

5

使用过滤器

const newArray = inputArr.filter(element => ![97, 32, 6].includes(element));

filter 函数会创建一个新的数组。它通过遍历原数组中的每一个元素来确定应该在新数组中包含哪些元素,如果对于当前元素返回 true,则将其添加到新数组中。
element => ![97, 32, 6].includes(element 表示我们正在询问数组 [97, 32, 6] 是否具有当前元素的值。由于我们不想将其添加到列表中,因此我们在行前面写入 !,因为我们希望发生相反的情况。

好的,我会简要解释一下。 - Pavlo

4

当你删除一个元素时,你也必须减少i的值。

为什么?

因为splice方法会改变数组的内容,元素的索引也会改变。所以,当你需要从数组中连续97个元素时进行删除操作,你必须减少i的值。

当你从数组中删除第一个97元素时,下一个97元素的索引也会改变,但是i却在不断增加。

var inputArr = [3, 97, 32, 6, 97, 2, 9,32, 1, 32, 97, 97, 6, -1, 5];

function removeItem(array, item) {
 for(i = 0; i<array.length; i++){
  if(array[i] == item) {
   array.splice(array.indexOf(item), 1);
                        i--;
  }
    }
}
removeItem(inputArr, 97); 
removeItem(inputArr, 32); 
removeItem(inputArr, 6);
document.getElementById("output").innerHTML = inputArr;
<p id="output"></p>

为了更简单的解决方案,您可以使用 filter 方法,通过传递一个 callback 函数作为参数。

var inputArr = [3, 97, 32, 6, 97, 2, 9,32, 1, 32, 97, 97, 6, -1, 5];

function removeItem(array, item) {
    return array.filter(i => i !== item);
}
inputArr = removeItem(inputArr, 97); 
inputArr = removeItem(inputArr, 32);
inputArr = removeItem(inputArr, 6);

console.log(inputArr);


2

有点棘手

当您获得匹配时,使用splice()函数,因此(i+1)个元素变成了i。但是下一次迭代从i+1开始,因此它不匹配第i个元素(即第i+1个元素)。

这里的最后两个97是连续的,因此只匹配了一个。

请尝试以下操作 -

function removeItem(array, item) {
    for(i = 0; i<array.length; i++){
        if(array[i] == item) {
            array.splice(array.indexOf(item), 1);
            i--;
        }
    }
}

谢谢。现在我明白了。那有点棘手。祝你有美好的一天。 - Kiran Dash

1
问题在于当 for-loop 执行时,您对元素进行修改,索引也会被修改。
更好的方法是使用 .filter() 函数。
看一下这段代码片段。

var inputArr = [3, 97, 32, 6, 97, 2, 9, 32, 1, 32, 97, 97, 6, -1, 5];

function removeItem(array, item) { 
  return array.filter((i) => i !== item);
}

inputArr = removeItem(inputArr, 97);
inputArr = removeItem(inputArr, 32);
inputArr = removeItem(inputArr, 6);

document.getElementById("output").innerHTML = inputArr;
<p id="output"></p>

看到了吗?数组已经被过滤了。

资源


感谢您的详细解释。 - Kiran Dash

1
在使用splice后,你必须将i减1。
array.splice(array.indexOf(item), 1);
i--;

谢谢。我现在已经弄清楚了。 - Kiran Dash

0

这是 ES5 版本,尤其在数组稀疏时运行更快。

function removeAll( array, item ) {
    for (var i = 0; (i = array.indexOf(item, i)) >= 0; array.splice(i, 1));
}
var inputArr = [3, 97, 32, 6, 97, 2, 9, 32, 1, 32, 97, 97, 6, -1, 5];

removeAll(inputArr, 97);
removeAll(inputArr, 32);
removeAll(inputArr, 6);

console.log(inputArr);


0

你应该像这样添加 i--

var inputArr = [3, 97, 32, 6, 97, 2, 9, 32, 1, 32, 97, 97, 6, -1, 5];

function removeItem(array, item) {
    for (i = 0; i < array.length; i++) {
        if (array[i] == item) {
            array.splice(array.indexOf(item), 1);
            i--;
        }
    }
}
removeItem(inputArr, 97);
removeItem(inputArr, 32);
removeItem(inputArr, 6);

document.getElementById('output').innerHTML = inputArr;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接