使用UnderscoreJS从数组中删除一个元素

144

假设我有以下代码:

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

我想要从该数组中移除 id=3 的元素。是否有一种方法可以不使用splice来实现呢?也许可以使用underscore或类似的东西吗?

谢谢!


如果您不想创建一个新的数组,那么切片是唯一的选择。我敢打赌underscore也使用它(如果存在这样的方法)。 - Felix Kling
6
拼接有什么问题? - Šime Vidas
你查看过 Underscore 的参考文档了吗? - Šime Vidas
只使用纯JavaScript,这是按对象属性从数组中删除对象的副本。 - Felix Kling
5
好的,它不是重复的,因为它有下划线标签。 - Garis M Suero
显示剩余2条评论
12个回答

288

只使用纯JavaScript,这个问题已经有答案了:按对象属性从数组中删除对象

使用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。 这也在其他问题中显示,并且underscore似乎没有提供任何有用的函数。

1
没错,这个完美地解决了,我查看了下划线的文档,但是没有很理解如何使用without函数。谢谢! - climboid
10
在这里使用_.reject或者_.filter()会不会更加高效呢?如果使用它们,只需要遍历列表两次就可以筛选出一个项。 - Rick Strahl
1
这可能是一个重复的问题,但这是更好的答案。 - Michael J. Calkins
2
@RickStrahl 您是正确的。在这里,_.reject看起来更好一些。 - Tarik
1
要弹出最后一个元素,请使用 arr.pop() - Emile Bergeron
显示剩余2条评论

101

您可以使用 Underscore .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


我认为你的意思是:var filtered = _.filter(arr, function(item) { return item.id !== 3 }); - tbh__
2
@tbh__ _() 会创建一个包装器,让你可以调用 underscore 方法来操作集合。 - Sushanth --
多年来一直在使用下划线,我从未知道这一点。谢谢。 - tbh__

39

使用 Underscore _.reject() 方法:

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

通过ES6,您可以使用arr = _.reject(arr, d => d.id === 3 );这个方法。 - greenafrican

18

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对象传递给without的情况。如果您将{ Name:“Sam”,Age:19 }传递给without而不是变量sam,则它将不再起作用。 [Fiddle](https://jsfiddle.net/mx8k13vd/) - Adam

6

如果您正在过滤字符串并且正在寻找不区分大小写的筛选器,请注意谨慎。 _.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);
}

2

您可以像这样使用纯JavaScript的Array#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);

注意:

  • 这两种方法都是纯函数式方法(即它们不会修改现有的数组)。
  • 这些方法不需要使用外部库(仅使用原生JavaScript就足够了)。

2
或者另一种方便的方式:
_.omit(arr, _.findWhere(arr, {id: 3}));

我的两分钱意见


1
omit在object上工作并返回一个object。因此,在处理Arrays时,我们可能希望在删除元素后得到一个array,这样就不太好用了。 - ScrapCode
1
所以,*_.without* 就是你在寻找的: => [2, 3, 4]``` - Nadeem

0

我曾经尝试过这种方法

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

可能还有更好的方法,就像用户提供的上述解决方案一样


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:1,name:'a'},{id:2,name:'c'}]


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