【问题标题】:JavaScript remove all occurrences of a value from an arrayJavaScript 从数组中删除所有出现的值
【发布时间】:2018-02-04 12:36:37
【问题描述】:

我正在使用下面的 sn-p 从数组中删除所有出现的值(即本例中的 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;
&lt;p id="output"&gt;&lt;/p&gt;

【问题讨论】:

  • 您在迭代数组时正在对其进行变异。通常这是个坏主意。因为每次删除某些东西时,数组长度都会发生变化。
  • 尤里·塔拉班科。谢谢(你的)信息。我会记住的。

标签: javascript arrays


【解决方案1】:

问题与兄弟 97s - 1, 32, 97, 97, 6 有关。当您按此顺序拼接前 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);

【讨论】:

  • 感谢您的精彩解释。
  • 或者干脆removeItems = (a, b) =&gt; a.filter(x =&gt; !b.includes(x))
【解决方案2】:

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

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

    while (i--) {
        if (array[i] === item) {
            array.splice(array.indexOf(item), 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);

【讨论】:

    【解决方案3】:

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

    为什么会这样?

    因为splice 方法改变了数组的内容,元素的索引也改变了。因此,当您需要 remove 数组中连续的 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;
    &lt;p id="output"&gt;&lt;/p&gt;

    为了更简单的解决方案,您可以通过将callback 函数作为参数传递来使用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);
    
    console.log(inputArr);

    【讨论】:

      【解决方案4】:

      使用过滤器

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

      filter 所做的是它创建了一个新的array。为了确定新的array应该是什么,它需要遍历旧数组中的每个element,如果我们为当前的element返回true,那么它将被添加到新的array .

      element =&gt; ![97, 32, 6].includes(element) 表示我们正在询问array [97, 32, 6] 是否具有当前element 的值。由于我们不想将其添加到列表中,所以我们在行前写!,因为我们希望发生相反的情况。

      【讨论】:

      • 好的,我简单解释一下
      【解决方案5】:

      有点棘手

      所以当你得到一个匹配时,你会做 splice(),因此第 (i+1) 个元素会出现在 i 中。但是下一次迭代从 i+1 开始,所以它与第 i 个元素(即第 i+1 个元素)不匹配。

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

      试试这个 -

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

      【讨论】:

      • 谢谢。现在我明白了。那有点棘手。祝你有美好的一天。
      【解决方案6】:

      拼接后你必须将 i 减 1。

      array.splice(array.indexOf(item), 1);
      i--;
      

      【讨论】:

      • 谢谢。现在想通了。
      【解决方案7】:

      问题是您在执行 for-loop 时进行了修改,元素的索引也被修改了。

      更好的方法是使用.filter() 函数。

      看这段代码sn-p

      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;
      &lt;p id="output"&gt;&lt;/p&gt;

      看到了吗?数组已过滤。

      资源

      【讨论】:

      • 感谢您的精彩解释。
      【解决方案8】:

      这是一个 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);

      【讨论】:

        【解决方案9】:

        你应该像这样添加 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;
        

        【讨论】:

          猜你喜欢
          • 2022-06-28
          • 2010-11-12
          • 1970-01-01
          • 2020-12-28
          • 2017-07-22
          • 1970-01-01
          • 2016-07-13
          相关资源
          最近更新 更多