【问题标题】:How to remove item from array by value? [duplicate]如何按值从数组中删除项目? [复制]
【发布时间】:2011-04-26 15:34:02
【问题描述】:

有没有从 JavaScript 数组中删除项目的方法?

给定一个数组:

var ary = ['three', 'seven', 'eleven'];

我想做这样的事情:

removeItem('seven', ary);

我已经查看了splice(),但它只删除了位置编号,而我需要一些东西来删除一个项目的值。

【问题讨论】:

标签: javascript arrays


【解决方案1】:

如果你有唯一的值并且顺序无关紧要,使用Set,它有delete()

var mySet = new Set(['three', 'seven', 'eleven']);
mySet.delete('seven'); // Returns true, successfully removed    
[...mySet];            // Returns ['three', 'eleven']

【讨论】:

    【解决方案2】:

    您可以像这样使用indexOf method

    var index = array.indexOf(item);
    if (index !== -1) {
      array.splice(index, 1);
    }
    

    注意You'll need to shim it for IE8 and below

    var array = [1,2,3,4]
    var item = 3
    
    var index = array.indexOf(item);
    array.splice(index, 1);
    
    console.log(array)

    【讨论】:

    • 并在索引不是-1时循环它
    • 最好只检查与-1不同的拼接,有数以百万计的选项,明智地选择jsperf.com/not-vs-gt-vs-ge/4
    • 如果你使用jquery,你可以使用$.inArray而不是indexOf,这是跨浏览器兼容的。
    • 确保 index!==(-1) ,即 item 存在于数组中,否则将拼接出数组中的最后一个元素。
    【解决方案3】:

    您可以创建自己的方法,传递数组和要删除的值:

    function removeItem(arr, item){
     return arr.filter(f => f !== item)
    }
    

    然后你可以这样调用:

    ary = removeItem(ary, 'seven');
    

    【讨论】:

      【解决方案4】:

      当您需要删除数组中多次出现的值时(例如 [1,2,2,2,4,5,6])。

      function removeFrmArr(array, element) {
        return array.filter(e => e !== element);
      };
      var exampleArray = [1,2,3,4,5];
      removeFrmArr(exampleArray, 3);
      // return value like this
      //[1, 2, 4, 5]
      

      您可以使用 splice 从数组中删除单个元素,但 splice 无法从数组中删除多个相似元素。

      function singleArrayRemove(array, value){
        var index = array.indexOf(value);
        if (index > -1) array.splice(index, 1);
        return array;
      }
      var exampleArray = [1,2,3,4,5,5];
      singleArrayRemove(exampleArray, 5);
      // return value like this
      //[1, 2, 3, 4, 5]
      

      【讨论】:

      • 您应该考虑在您的代码中添加一些解释。
      • 第 5 行应该是 removeFrmArr(exampleArray, 3);,当前代码会抛出 ReferenceError。
      【解决方案5】:

      简单

      var ary = ['three', 'seven', 'eleven'];
      var index = ary.indexOf('seven'); // get index if value found otherwise -1
      
      if (index > -1) { //if found
        ary.splice(index, 1);
      }
      

      【讨论】:

      • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation would greatly improve its long-term value 通过展示为什么这是一个很好的解决问题的方法,并将使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
      • 在我的情况下效果最好,因为我想从一个数组中删除,并将值(要删除)存储到一个变量中。谢谢!
      【解决方案6】:

      这样查看:

      delete this.arrayName[this.arrayName.indexOf(value)];
      

      参考:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete

      【讨论】:

      • 对数组中的项目使用 delete 会在数组中留下一个“空槽”(使 array.length 保持不变)。可能不是 OP 或任何阅读此答案的人正在寻找的东西。
      【解决方案7】:

      您可以通过以下两种方式做到这一点:

      const arr = ['1', '2', '3', '4'] // we wanna delete number "3"
      
      1. 第一种方式:

        arr.indexOf('3') !== -1 && arr.splice(arr.indexOf('3'), 1)
        
      2. 第二种方式(ES6)特别无变异

        const newArr = arr.filter(e => e !== '3')
        

      【讨论】:

        【解决方案8】:

        最简单的解决方案是:

        array - 移除某些元素的数组 valueForRemove; valueForRemove - 移除元素;

        array.filter(arrayItem => !array.includes(valueForRemove));
        

        更简单:

        array.filter(arrayItem => arrayItem !== valueForRemove);
        

        不漂亮,但有效:

        array.filter(arrayItem => array.indexOf(arrayItem) != array.indexOf(valueForRemove))
        

        不漂亮,但有效:

        while(array.indexOf(valueForRemove) !== -1) {
          array.splice(array.indexOf(valueForRemove), 1)
        }
        

        附: filter() 方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

        【讨论】:

        • 那甚至不接近正确答案?您应该为工作示例编辑它。现在很混乱。
        • 虽然我喜欢这种方法,因为它使用了不可变的数据结构,但这并不是一个包罗万象的解决方案,因为有时开发人员确实想要对数组进行原地变异跨度>
        • filter() 方法创建一个新数组,其中包含所有通过所提供函数实现的测试的元素。见developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
        • 这作为分配的右侧:newArray = array.filter... 然后:array = newArray 并且项目从 array 消失。
        • 关于 filter() 的文档是绝对可以理解的。
        【解决方案9】:

        在所有唯一值中,您可以:

        a = new Set([1,2,3,4,5]) // a = Set(5) {1, 2, 3, 4, 5}
        a.delete(3) // a = Set(5) {1, 2, 4, 5} 
        [...a] // [1, 2, 4, 5]
        

        【讨论】:

          【解决方案10】:

          ES6 方式。

          const commentsWithoutDeletedArray = commentsArray.filter(comment => comment.Id !== commentId);
          

          【讨论】:

          • 我认为 javascript 中的 mapreduce 函数非常快,但 splice 仍然会更快。所以更好的实现可能是const removeArrayItem = (arr, itemToRemove) => { return arr.includes(itemToRemove)? arr.splice(arr.indexOf(itemToRemove), 1): arr }
          • @robertotomás 我更喜欢可读性而不是轻微的性能提升。
          • 嘿@OliverDixon 你能解释一下comment.Id !== commentId 现在我要删除的commecnt 是5 现在在过滤器5 !== 5 它是假的那么如何删除它:\?
          • @OliverDixon 如果您需要性能,您可以简单地将不可读的代码包装到您自己的可读函数中。
          【解决方案11】:

          您可以使用 Lodash _.remove 函数实现此目的。

          var array = ['three', 'seven', 'eleven'];
          var evens = _.remove(array, function(e) {
            return e !== 'seven';
          });
          
          console.log(evens);
          <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/lodash@4.17.10/lodash.min.js"></script>

          【讨论】:

            【解决方案12】:

            在全局函数中我们不能直接传递自定义值,但是有很多方法如下

             var ary = ['three', 'seven', 'eleven'];
             var index = ary.indexOf(item);//item: the value which you want to remove
            
             //Method 1
             ary.splice(index,1);
            
             //Method 2
             delete ary[index]; //in this method the deleted element will be undefined
            

            【讨论】:

            • delete 不应该使用,因为它只删除值但留下空间。
            【解决方案13】:

            真的,我不明白为什么不能解决这个问题

            arr = arr.filter(value => value !== 'seven');
            

            或者也许你想使用 vanilla JS

            arr = arr.filter(function(value) { return value !== 'seven' });
            

            【讨论】:

            • 可能是因为它没有从数组中删除项目?
            • 是的,它没有,它创建一个没有字符串'seven'的新数组
            • 它对我有用,谢谢。 arr = arr.filter(value => value !== 'seven');
            【解决方案14】:

            您可以使用lodash pull function

            var ary = ['three', 'seven', 'eleven'];
            _.pull(ary, 'seven'); // ['three', 'eleven']
            console.log(ary)
            <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.6.1/lodash.js"></script>

            【讨论】:

            • 不必要地使用 javascript 导入
            • @Chiaro,为我提供正确的解决方案。我会很开心。
            • 好吧,尽量使用默认值,除非你的大部分代码库都会使用那个特定的库。例如。在这里,您可以使用“过滤器”轻松地在 4 行代码中创建自己的方法
            • 好的,谢谢 :-)
            【解决方案15】:
            let arr = [5, 15, 25, 30, 35];
            console.log(arr); //result [5, 15, 25, 30, 35]
            let index = arr.indexOf(30);
            
            if (index > -1) {
               arr.splice(index, 1);
            }
            console.log(arr); //result [5, 15, 25, 35]
            

            【讨论】:

              【解决方案16】:

              您可以从Lodash 使用withoutpull

              const _ = require('lodash');
              _.without([1, 2, 3, 2], 2); // -> [1, 3]
              

              【讨论】:

                【解决方案17】:

                鉴于没有漂亮的,这里有一个简单且可重用的 ES6 函数。

                const removeArrayItem = (arr, itemToRemove) => {
                  return arr.filter(item => item !== itemToRemove)
                }
                

                用法:

                const items = ['orange', 'purple', 'orange', 'brown', 'red', 'orange']
                removeArrayItem(items, 'orange')
                

                【讨论】:

                • removeArrayItem 方法不会从数组中删除项目。它创建没有项目的新数组。
                • 正确@WebBrother。从“消费者”的角度来看,实现并不是我真正关心的问题——如果我给它一个数组和一个项目,我会得到一个删除了项目的数组,所以这个名字对我来说很有意义。想法?
                • 如果您打算使用 ES6,请确保您使用了正确的比较(避免使用 !== 而使用 !Object.is(item, itemToRemove)。
                【解决方案18】:

                一个适用于所有浏览器且没有任何框架的非常干净的解决方案是分配一个新数组并简单地返回它而不包含您要删除的项目:

                /**
                 * @param {Array} array the original array with all items
                 * @param {any} item the time you want to remove
                 * @returns {Array} a new Array without the item
                 */
                var removeItemFromArray = function(array, item){
                  /* assign a empty array */
                  var tmp = [];
                  /* loop over all array items */
                  for(var index in array){
                    if(array[index] !== item){
                      /* push to temporary array if not like item */
                      tmp.push(array[index]);
                    }
                  }
                  /* return the temporary array */
                  return tmp;
                }
                

                【讨论】:

                • +1 获得干净的解决方案。当有时我们需要一个更纯粹的解决方案时,太多的答案往往会建议一个或另一个第三方资源(而且它们都很棒,只是不是在所有用例中都很好)。
                【解决方案19】:

                这是一个使用 jQuery 的 inArray function 的版本:

                var index = $.inArray(item, array);
                if (index != -1) {
                    array.splice(index, 1);
                }
                

                【讨论】:

                • Splice 支持从末尾获取负索引,因此如果未找到该项目,此代码将删除数组中的最后一项。
                • @dman2306 嗯,直到现在才看到您的评论,但这是一个非常好的观点。已针对该问题进行了修复。
                【解决方案20】:

                这样查看:

                for(var i in array){
                    if(array[i]=='seven'){
                        array.splice(i,1);
                        break;
                    }
                }
                

                在函数中:

                function removeItem(array, item){
                    for(var i in array){
                        if(array[i]==item){
                            array.splice(i,1);
                            break;
                        }
                    }
                }
                
                removeItem(array, 'seven');
                

                【讨论】:

                • 请记住,如果您将此代码修改为不“中断”并继续循环删除多个项目,则需要在拼接后立即重新计算 i 变量,如下所示:i--。那是因为你只是缩小了数组,否则你最终会跳过一个元素。
                • 添加到我上面的评论中,代码将是: for (var i = 0; i
                • 嗨... 问题,如何删除多个数组?我试过removeItem(array, 'seven, eight'),但它不起作用。
                【解决方案21】:

                单线就可以了,

                var ary = ['three', 'seven', 'eleven'];
                
                // Remove item 'seven' from array
                var filteredAry = ary.filter(function(e) { return e !== 'seven' })
                //=> ["three", "eleven"]
                
                // In ECMA6 (arrow function syntax):
                var filteredAry = ary.filter(e => e !== 'seven')
                

                这利用了 JS 中的filter 函数。它在 IE9 及更高版本中受支持。

                它的作用(来自文档链接)

                filter() 为数组中的每个元素调用一次提供的回调函数,并构造一个包含所有值的新数组,回调为其返回一个强制为 true 的值。回调仅针对已分配值的数组索引调用;对于已被删除或从未被赋值的索引,它不会被调用。未通过回调测试的数组元素将被简单地跳过,并且不包含在新数组中。

                所以基本上,这与所有其他 for (var key in ary) { ... } 解决方案相同,只是从 IE6 开始支持 for in 构造。

                基本上,与for in 构造 (AFAIK) 相比,过滤器是一种看起来更好(并且可链接)的便捷方法。

                【讨论】:

                • 想知道这个美妙的单线不会得到更多的爱。 +1 没有循环。使用&& 作为值可以添加任意数量的值。
                • @bamboon 过滤功能检查元素是否符合条件。该函数对每个元素一一执行,并在返回 true 时,生成的数组将保留该元素。在false 上省略。
                • 这真的很简单,@SLaks 提到它会创建数组的副本,并且不会影响对变量的引用。
                • 请注意,这应该用作array = array.filter(),而不仅仅是array.filter()
                • 更新了@JeffreyRoosendaal 贡献的答案(filter() does not mutate the array on which it is called. from developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)。
                【解决方案22】:

                无损移除:

                function removeArrayValue(array, value)
                {
                    var thisArray = array.slice(0); // copy the array so method is non-destructive
                
                    var idx = thisArray.indexOf(value); // initialise idx
                
                    while(idx != -1)
                    {
                        thisArray.splice(idx, 1); // chop out element at idx
                
                        idx = thisArray.indexOf(value); // look for next ocurrence of 'value'
                    }
                
                    return thisArray;
                }
                

                【讨论】:

                  【解决方案23】:

                  //编辑感谢MarcoCI的建议

                  试试这个:

                  function wantDelete(item, arr){
                    for (var i=0;i<arr.length;i++){
                      if (arr[i]==item){
                        arr.splice(i,1); //this delete from the "i" index in the array to the "1" length
                        break;
                      }
                    }  
                  }
                  var goodGuys=wantDelete('bush', ['obama', 'bush', 'clinton']); //['obama', 'clinton']
                  

                  希望对你有帮助

                  【讨论】:

                  • 一个解释,即使是简短的,也比仅仅转储一段代码要好。
                  • 不要将for in 用于数组,这是不好的做法,如果有人触摸了数组原型,你就完了。
                  【解决方案24】:

                  您可以使用underscore.js。它真的让事情变得简单。

                  例如,用这个:

                  var result = _.without(['three','seven','eleven'], 'seven');
                  

                  result 将是['three','eleven']

                  在您的情况下,您必须编写的代码是:

                  ary = _.without(ary, 'seven')
                  

                  它减少了您编写的代码。

                  【讨论】:

                  • 我从来没有说过不要在其他地方使用图书馆。如果代码看起来更干净,那么我不介意包含一个库。为什么人们使用 jquery ,为什么不使用原始 javascript 呢?
                  • @vatsal - 因为库开发人员可以专注于使库函数背后的函数快速、简洁和跨浏览器,而我可以专注于我的应用程序及其用途。它节省了我思考的时间,让我有更多的时间来改进应用程序,而不用担心构成我的应用程序的小功能。轮子已经有人发明了,为什么每次造车都要重做?
                  • 嗨,Kelvin,我完全同意你的看法。一个人发表了评论,后来又删除了,他说使用像下划线这样的库并不酷,我们不应该接受这样的答案。我试图回答它。
                  • 请注意,这不会修改数组;将返回一个新数组。
                  【解决方案25】:

                  诀窍是从头到尾遍历数组,因此在删除元素时不会弄乱索引。

                  var deleteMe = function( arr, me ){
                     var i = arr.length;
                     while( i-- ) if(arr[i] === me ) arr.splice(i,1);
                  }
                  
                  var arr = ["orange","red","black", "orange", "white" , "orange" ];
                  
                  deleteMe( arr , "orange");
                  

                  arr 现在是 ["red", "black", "white"]

                  【讨论】:

                    【解决方案26】:

                    我使用了投票最多的选项并创建了一个函数,该函数将使用另一个不需要的单词数组来清除一个单词数组:

                    function cleanArrayOfSpecificTerms(array,unwantedTermsArray) {
                      $.each(unwantedTermsArray, function( index, value ) {
                        var index = array.indexOf(value);
                        if (index > -1) {
                          array.splice(index, 1);        
                        }
                      });
                      return array;
                    }
                    

                    要使用,请执行以下操作:

                    var notInclude = ['Not','No','First','Last','Prior','Next', 'dogs','cats'];
                    var splitTerms = ["call", "log", "dogs", "cats", "topic", "change", "pricing"];
                    
                    cleanArrayOfSpecificTerms(splitTerms,notInclude)
                    

                    【讨论】:

                      【解决方案27】:

                      你所追求的是过滤器

                      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

                      这将允许您执行以下操作:

                      var ary = ['three', 'seven', 'eleven'];
                      var aryWithoutSeven = ary.filter(function(value) { return value != 'seven' });
                      console.log(aryWithoutSeven); // returns ['three', 'eleven']
                      

                      在其他地方的这个帖子中也注意到了这一点:https://stackoverflow.com/a/20827100/293492

                      【讨论】:

                      • 这不会改变数组。
                      • 否;将变量分配为指向一个新对象。如果您对原始数组有其他引用,它们不会受到影响。
                      【解决方案28】:

                      请不要使用带有delete 的变体 - 它会在数组中造成一个洞,因为它不会在删除的项目之后重新索引元素。

                      > Array.prototype.remove=function(v){
                      ...     delete this[this.indexOf(v)]
                      ... };
                      [Function]
                      > var myarray=["3","24","55","2"];
                      undefined
                      > myarray.remove("55");
                      undefined
                      > myarray
                      [ '3', '24', , '2' ]
                      

                      【讨论】:

                        【解决方案29】:

                        另一种变化:

                        if (!Array.prototype.removeArr) {
                            Array.prototype.removeArr = function(arr) {
                                if(!Array.isArray(arr)) arr=[arr];//let's be nice to people who put a non-array value here.. that could be me!
                                var that = this;
                                if(arr.length){
                                    var i=0;
                                    while(i<that.length){
                                        if(arr.indexOf(that[i])>-1){
                                            that.splice(i,1);
                                        }else i++;
                                    }
                                }
                                return that;
                            }
                        }
                        

                        又是循环内的 indexOf() ,但假设要删除的数组相对于要清理的数组很小;每次删除都会缩短 while 循环。

                        【讨论】:

                          【解决方案30】:
                          //This function allows remove even array from array
                          var removeFromArr = function(arr, elem) { 
                              var i, len = arr.length, new_arr = [],
                              sort_fn = function (a, b) { return a - b; };
                              for (i = 0; i < len; i += 1) {
                                  if (typeof elem === 'object' && typeof arr[i] === 'object') {
                                      if (arr[i].toString() === elem.toString()) {
                                          continue;
                                      } else {                    
                                          if (arr[i].sort(sort_fn).toString() === elem.sort(sort_fn).toString()) {
                                              continue;
                                          }
                                      }
                                  }
                                  if (arr[i] !== elem) {
                                      new_arr.push(arr[i]);
                                  }
                              }
                              return new_arr;
                          }
                          

                          使用示例

                          var arr = [1, '2', [1 , 1] , 'abc', 1, '1', 1];
                          removeFromArr(arr, 1);
                          //["2", [1, 1], "abc", "1"]
                          
                          var arr = [[1, 2] , 2, 'a', [2, 1], [1, 1, 2]];
                          removeFromArr(arr, [1,2]);
                          //[2, "a", [1, 1, 2]]
                          

                          【讨论】:

                            猜你喜欢
                            • 2020-07-17
                            • 2011-10-30
                            • 2019-10-03
                            • 2012-02-11
                            • 1970-01-01
                            • 2021-10-19
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多