【问题标题】:Remove an item from array using UnderscoreJS使用 UnderscoreJS 从数组中删除一个项目
【发布时间】:2013-06-04 08:34:49
【问题描述】:

假设我有这个代码

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

我想从数组中删除 id = 3 的项目。有没有办法做到这一点而不拼接?使用下划线之类的东西?

谢谢!

【问题讨论】:

  • 如果不想新建数组,拼接是唯一的选择。我敢打赌 underscore 也使用它(在内部,如果存在这样的方法)。
  • 拼接有什么问题?
  • 你检查过下划线的引用吗?
  • 仅使用纯 JavaScript,这是 remove objects from array by object property 的副本。
  • well 不是重复的,因为它有 underscore.js 的标签

标签: javascript underscore.js


【解决方案1】:

仅使用纯 JavaScript,已经回答了这个问题:remove objects from array by object property

使用 underscore.js,您可以将 .findWhere.without 结合起来:

var arr = [{
  id: 1,
  name: 'a'
}, {
  id: 2,
  name: 'b'
}, {
  id: 3,
  name: 'c'
}];

//substract third
arr = _.without(arr, _.findWhere(arr, {
  id: 3
}));
console.log(arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

虽然,由于在这种情况下无论如何您都在创建一个新数组,您可以简单地使用_.filter 或本机Array.prototype.filter 函数(就像在另一个问题中所示)。然后你将只迭代数组一次,而不是像这里那样可能两次。

如果你想就地修改数组,你必须使用.splice。这也显示在另一个问题中,并且 undescore 似乎没有为此提供任何有用的功能。

【讨论】:

  • 是的,这很好用,我确实查看了下划线文档,但不太明白如何在没有的情况下将其拉出。谢谢!
  • 这里的 _.reject 或 _.filter() 不会更有效吗?你最终会得到列表的两次迭代,只是为了拉出一个项目。
  • 这可能是重复的,但这是更好的答案。
  • @RickStrahl 你是对的。 _.reject 在这里看起来是一个更好的选择。
  • @lukaserat 弹出最后一个元素,使用arr.pop()...
【解决方案2】:

你可以使用下划线.filter

    var arr = [{
      id: 1,
      name: 'a'
    }, {
      id: 2,
      name: 'b'
    }, {
      id: 3,
      name: 'c'
    }];

    var filtered = _(arr).filter(function(item) {
         return item.id !== 3
    });

也可以写成:

var filtered = arr.filter(function(item) {
    return item.id !== 3
});

var filtered = _.filter(arr, function(item) {
    return item.id !== 3
});

Check Fiddle

你也可以使用.reject

【讨论】:

  • 我想你的意思是:var filters = _.filter(arr, function(item) { return item.id !== 3 });
  • @tbh__ _() 将围绕集合创建一个包装器,让您可以调用下划线方法。
  • 多年来一直使用下划线,我从来不知道这一点。谢谢
【解决方案3】:

使用下划线_.reject():

arr = _.reject(arr, function(d){ return d.id === 3; });

【讨论】:

  • 使用 es6 你可以做到arr = _.reject(arr, d => d.id === 3 );
【解决方案4】:

Underscore 有一个 _without() 方法,非常适合从数组中删除项目,尤其是当您有要删除的对象时。

返回删除所有值实例的数组副本。

_.without(["bob", "sam", "fred"], "sam");

=> ["bob", "fred"]

也适用于更复杂的对象。

var bob = { Name: "Bob", Age: 35 };
var sam = { Name: "Sam", Age: 19 };
var fred = { Name: "Fred", Age: 50 };

var people = [bob, sam, fred]

_.without(people, sam);

=> [{ Name: "Bob", Age: 35 }, { Name: "Fred", Age: 50 }];

如果您没有要删除的项目,只是它的一个属性,您可以使用_.findWhere,然后使用_.without

【讨论】:

  • 注意:这仅适用于您将 sam 对象传递给 without。如果您改为将{ Name: "Sam", Age: 19 } 传递给不带变量sam 而不是变量sam,则它不再起作用。 Fiddle
【解决方案5】:

如果您要过滤字符串并寻找不区分大小写的过滤器,请务必小心。 _.without() 区分大小写。您也可以使用 _.reject(),如下所示。

var arr = ["test","test1","test2"];

var filtered = _.filter(arr, function(arrItem) {
    return arrItem.toLowerCase() !== "TEST".toLowerCase();
});
console.log(filtered);
// ["test1", "test2"]

var filtered1 = _.without(arr,"TEST");
console.log(filtered1);
// ["test", "test1", "test2"]

var filtered2 = _.reject(arr, function(arrItem){ 
    return arrItem.toLowerCase() === "TEST".toLowerCase();
});
console.log(filtered2);
// ["test1", "test2"]

【讨论】:

    【解决方案6】:

    其他答案创建数组的新副本,如果您想修改数组可以使用:

    arr.splice(_.findIndex(arr, { id: 3 }), 1);
    

    但这假设元素总是在数组中找到(因为如果没有找到它仍然会删除最后一个元素)。为了安全起见,您可以使用:

    var index = _.findIndex(arr, { id: 3 });
    if (index > -1) {
        arr.splice(index, 1);
    }
    

    【讨论】:

      【解决方案7】:

      或其他方便的方式:

      _.omit(arr, _.findWhere(arr, {id: 3}));
      

      我的 2 美分

      【讨论】:

      • 省略作用于object 并返回object。因此不适合使用Arrays,我们可能希望在删除元素后得到array
      • 所以,_.without 是您正在查看的内容:_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]
      【解决方案8】:

      使用可以像这样使用plain JavaScriptArray#filter方法:

      var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];
      
      var filteredArr = arr.filter(obj => obj.id != 3);
      
      console.log(filteredArr);

      或者,像这样使用Array#reduceArray#concat 方法:

      var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];
      
      var reducedArr = arr.reduce((accumulator, currObj) => {
        return (currObj.id != 3) ? accumulator.concat(currObj) : accumulator;
      }, []);
      
      console.log(reducedArr);

      注意:

      • 这两种方法都是纯函数方法(它们不会修改现有数组)。
      • 不,这些方法需要外部库(Vanilla JavaScript 就足够了)。

      【讨论】:

        【解决方案9】:

        我曾经尝试过这种方法

        _.filter(data, function(d) { return d.name != 'a' });
        

        可能还有更好的方法,例如用户提供的上述解决方案

        【讨论】:

          【解决方案10】:

          通过使用 underscore.js

          var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];
          
          var resultArr = _.reject(arr,{id:3});
          
          console.log(resultArr);
          

          结果将是 :: [{id:1name:'a'},{id:2,name:'c'}]

          【讨论】:

            【解决方案11】:

            你可以使用下划线的拒绝方法,下面将返回一个新的数组,它不会有特定匹配的数组

            arr = _.reject(arr, function(objArr){ return objArr.id == 3; });
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-02-11
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-10-22
              • 1970-01-01
              • 2014-01-16
              相关资源
              最近更新 更多