使用UnderscoreJS从数组中删除项目


137

说我有这个代码

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

我想从数组中删除id = 3的项目。有没有没有拼接的方法吗?可能使用下划线或类似内容?

谢谢!


如果您不想创建新的数组,则拼接是唯一的选择。我敢打赌,下划线也要使用它(内部,如果存在这种方法的话)。
Felix Kling 2013年

6
拼接有什么问题?
森达维达斯

您是否检查了下划线的参考?
森达维达斯

仅使用普通的JavaScript,这是按object property从数组删除对象的重复。
Felix Kling 2013年

5
好的不是重复的,因为它具有underscore.js的标签
Garis M Suero

Answers:


279

仅使用普通的JavaScript,就已经回答了这一问题:通过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似乎没有为此提供任何有用的功能。


1
是的,这很完美,我确实查阅了下划线文档,但还不太了解如何在没有它的情况下使用它。谢谢!
climboid

10
_.reject或_.filter()在这里效率不是很多吗?您最终会得到列表的两次迭代,只是要取出一项。
里克·斯特拉尔

1
这可能是重复的,但这是更好的答案。
Michael J. Calkins

2
@RickStrahl你是对的。_.reject在这里看起来是更好的选择。
塔里克

1
@lukaserat弹出最后一个元素,使用arr.pop()...
Emile Bergeron

96

您可以使用下划线 .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
});

检查小提琴

您也可以使用 .reject


我认为您的意思是:varfiltered = _.filter(arr,function(item){return item.id!== 3});
tbh__

2
@tbh__ _()将在集合周围创建一个包装器,使您可以调用下划线方法。
苏珊思-

多年使用下划线,我从来不知道这一点。谢谢
tbh__


16

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


2
注意:这仅适用于因为将sam对象传递给了not。如果改为传递{ Name: "Sam", Age: 19 }给no而不是变量sam,它将不再起作用。小提琴
亚当

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"]

4

其他答案将创建阵列的新副本,如果您想就地修改阵列,则可以使用:

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

但这假定将始终在数组内找到该元素(因为如果找不到该元素,它将仍然删除最后一个元素)。为了安全起见,您可以使用:

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

2

或另一种便捷的方式:

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

我的2美分


1
omit继续工作object并返回object。因此,对于在移除元素后Arrays我们可能会获得array回报的工作而言,这并不是一件好事。
ScrapCode

1
因此,_。without是您要查看的内容: _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]
Nadeem

2

使用可以使用纯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#reduce和这样的Array#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就足够了)。


0

通过使用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'}]


-1

您可以使用Underscore的reject方法,下面将返回一个新数组,该数组将不具有特定匹配项

arr = _.reject(arr, function(objArr){ return objArr.id == 3; });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.