Lodash从数组中删除重复项

369

这是我的数据:

[
    {
        url: 'www.example.com/hello',
        id: "22"    
    },
    {
        url: 'www.example.com/hello',
        id: "22"    
    },
    {
        url: 'www.example.com/hello-how-are-you',
        id: "23"    
    },
    {
        url: 'www.example.com/i-like-cats',
        id: "24"    
    },
    {
        url: 'www.example.com/i-like-pie',
        id: "25"    
    }
]

使用 Lodash,我如何删除具有重复 id 键的对象?可能需要使用 filter、map 和 unique,但不太确定。

我的实际数据集更大,有更多的键,但概念应该是相同的。

8个回答

659

_.unique在当前版本的Lodash(4.0.0)中已经不再起作用,因为发生了这个破坏性变化_.unique的功能被拆分成_.uniq_.sortedUniq_.sortedUniqBy_.uniqBy

您可以像这样使用_.uniqBy

_.uniqBy(data, function (e) {
  return e.id;
});

...或者像这样:

_.uniqBy(data, 'id');

文档:https://lodash.com/docs#uniqBy


对于旧版本的 Lodash(< 4.0.0):

假设数据应该根据每个对象的 id 属性进行去重,您的数据存储在变量 data 中,您可以像这样使用 _.unique() 函数:

_.unique(data, function (e) {
  return e.id;
});

或者只需这样:

_.uniq(data, 'id');

1
lodash 4.0.1文档已将此更改为uniqBy。仅使用uniq,我无论如何都不能让上面的示例运行。 - Will Lovett
4
在 Lodash 4.x 中,uniq() 只接受一个参数,该参数为数组。如@WillLovett所说,我们可以使用 uniqBy() 来解决这个问题。 - ersefuril
1
哦,天啊。为什么“uniq”要发音成“you-knee-queue”,而不是应该是“unique”呢…… - Josh M.

91

您可以使用 Lodash 方法 _.uniqWith,它在当前版本的 Lodash 4.17.2 中可用。

示例:

var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];

_.uniqWith(objects, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]

更多信息: https://lodash.com/docs/#uniqWith


6
这个方法适用于包含简单对象的大型数组,它将通过 _.uniqBy 函数对 docs 数组进行去重操作,该函数以 e.x + e.y 作为去重依据,从而提高去重速度。 - tagplus5
6
是的,但是在使用uniqBy时,你需要将属性作为第一个参数传递进去,如果你想按照多个属性使其唯一化,而这些属性你并不知道,那就不太方便了。 - dbrrt

29

使用 lodash 4+ 版本,您可以按特定属性或整个对象来删除重复对象,方法如下所示:

var users = [
  {id:1,name:'ted'},
  {id:1,name:'ted'},
  {id:1,name:'bob'},
  {id:3,name:'sara'}
];
var uniqueUsersByID = _.uniqBy(users,'id'); //removed if had duplicate id
var uniqueUsers = _.uniqWith(users, _.isEqual);//removed complete duplicates

来源:https://www.codegrepper.com/?search_term=Lodash+remove+duplicates+from+array


1
正在查找 var uniqueUsers = _.uniqWith(users, _.isEqual);//removed complete duplicates。您的回答值得更多的喜爱。 - Sydney C.
这正是我寻找的:_.uniqWith(users, _.isEqual) 用于无序对象。 - Teebu

22

或者简单地使用union,用于数组合并。

_.union([1,2,3,3], [3,5])

// [1,2,3,5]

2
我喜欢这个答案。虽然不是最易读的,但如果你从数学角度考虑它,它实际上是有效的。_.union([1, 2, 2, 1, 3]) => [1, 2, 3] - Sepehr
2
聪明而简洁 - Jean-Philippe Martin

19

对于一个简单的数组,你可以使用并集方法,但也可以使用:

_.uniq([2, 1, 2]);

10

只需使用_.uniqBy()即可。它创建一个无重复项的数组版本。

这是一种新方法,自4.0.0版本起可用。

_.uniqBy(data, 'id');

或者

_.uniqBy(data, obj => obj.id);

5

LODASH 4版本以下的大部分功能实现方式不同。相反,在版本4中,_.uniq进行了修改。我曾经有一个项目在几个月内进行过渡 (从V3 -> V4)

如果您遇到同样的情况并且需要更新许多函数,则可以分阶段进行,并在完成过渡后稍后再进行修复。这是我用来避免平台停机时间的技巧:

/* LODASH Version 3 & 4 Compatibility Mode */
if ((_.VERSION).charAt(0) <= 3){ //Detect LODASH version 3 or 4.
    //V3 or lower
    _.uniq(data, true, 'id');
} else {
    //V4 or Higher
    _.uniqBy(data, 'id');
}

同时,如果您查看lodash文档,对于大多数情况,您可以找到从版本低于4_.uniq迁移的两个函数:_.uniqBy(data, 'id')_.unionBy(data, 'id')。它们都会带来相同的结果。我个人猜想应该选择哪一个。最终我选择了这个:_.uniqBy(data, 'id')

2

您也可以使用unionBy来处理4.0.0及更高版本的数据,操作方式如下: let uniques = _.unionBy(data, 'id')


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