获取 JavaScript 数组中的所有唯一值(删除重复项)

Get all unique values in a JavaScript array (remove duplicates)

提问人:Mottie 提问时间:12/25/2009 最后编辑:casperOneMottie 更新时间:11/9/2023 访问量:3284769

问:

我有一个数字数组,我需要确保这些数字是唯一的。我在互联网上找到了下面的代码片段,它运行良好,直到数组中有零。我在 Stack Overflow 上找到了另一个看起来几乎完全一样的脚本,但它并没有失败。

所以为了帮助我学习,有人可以帮我确定原型脚本哪里出了问题吗?

Array.prototype.getUnique = function() {
 var o = {}, a = [], i, e;
 for (i = 0; e = this[i]; i++) {o[e] = 1};
 for (e in o) {a.push (e)};
 return a;
}
JavaScript 唯一 数组

评论

6赞 Mottie 2/13/2014
@hippietrail 这个较旧的问题是关于仅查找和返回重复项(我也感到困惑!我的问题更多的是关于为什么当数组中包含零时此函数会失败。
0赞 nurettin 12/30/2014
对于未来的读者来说,当开始发现你必须一直以算法方式修改数据结构的内容时(对它们进行排序、删除重复的元素等)或在每次迭代中搜索其中的元素时,可以安全地假设你首先使用了错误的数据结构,并开始使用更适合手头任务的数据结构(在这种情况下是哈希集而不是数组)。
0赞 Mottie 8/4/2015
我从其他地方复制了代码,很久以前......但这似乎很简单:=、=、=和=嗯,:Poobjectaarrayiindexe
0赞 Adeel Imran 12/26/2017
如何获取数组中的唯一值的可能重复
0赞 Nam Kim 11/19/2019
只是想指出,很多人建议使用 JavaScript Set 作为解决方案,请谨慎行事,因为它在 Internet Explorer 中不受支持。如果必须支持 IE,请使用 polyfill。

答:

17赞 Luca Matteis 12/25/2009 #1

那是因为 JavaScript 中的错误值。0

this[i]如果数组的值为 0 或任何其他虚假值,则为虚假值。

评论

1赞 Mottie 12/25/2009
啊,好吧,我现在明白了......但是有没有一个简单的修复程序来使其工作?
17赞 ephemient 12/25/2009 #2
Array.prototype.getUnique = function() {
    var o = {}, a = []
    for (var i = 0; i < this.length; i++) o[this[i]] = 1
    for (var e in o) a.push(e)
    return a
}

评论

1赞 Camilo Martin 5/23/2013
我认为如果数组包含对象/数组,这将不起作用,并且我不确定它是否会保留标量的类型。
1赞 ephemient 5/24/2013
是的,一切都被字符串化了。这可以通过存储原始值而不是仅仅存储一个来解决,尽管相等性比较仍然是字符串的(尽管在所有可能的 Javascript 相等中,它似乎并不太不合理)。o1
1赞 bortunac 11/17/2016
Array.prototype 只能使用不可枚举的方法进行扩展......Object.defineProperty(Array.prototype,“getUnique”,{}) ...但是使用帮助程序对象的想法非常好
13赞 Decebal 11/1/2011 #3

如果你使用的是 Prototype 框架,则无需执行“for”循环,您可以使用如下 http://prototypejs.org/doc/latest/language/Array/prototype/uniq/

var a = Array.uniq();  

这将产生一个没有重复项的重复数组。我遇到了你的问题,搜索一种计算不同数组记录的方法,所以在我使用后,有我的简单结果。 p.s. 对不起,如果我打错了什么uniq()size()

编辑:如果要转义未定义的记录,可能需要添加之前,如下所示:compact()

var a = Array.compact().uniq();  

评论

15赞 Decebal 11/1/2011
因为我找到了一个更好的答案,所以我认为主题是针对所有人的,而不仅仅是针对提问者
2赞 Lukas Liesis 7/10/2021
感谢时间机器,但 iirc 大约 15 年前 JS 社区进行了辩论,结果是 - 不要扩展原型,因为副作用会导致你以这种方式污染所有 JS 数组。
164赞 kornfridge 7/12/2012 #4

还可以使用下划线.js

console.log(_.uniq([1, 2, 1, 3, 1, 4]));
<script src="http://underscorejs.org/underscore-min.js"></script>

这将返回:

[1, 2, 3, 4]

评论

29赞 Jacob Dalton 4/27/2016
请这样做,伙计们。不要将某些东西顶到阵列原型上。请。
93赞 7/6/2018
@JacobDalton请不要这样做。没有必要仅仅为了一个小工作而添加一个额外的库,而这些工作可以用array = [...new Set(array)]
0赞 anshul 7/27/2021
@JacobDalton为什么不呢?将某些东西“顶起”到阵列上是否有缺点?
0赞 Aron 12/7/2022
如果您想使用对象相等语义查找唯一对象,Lodash 提供了 . 给。_.uniqWith(arrayOfObjects, _.isEqual)_.uniqWith([{a: 2}, {b: 3}, {a: 2}], _.isEqual)[{a: 2}, {b: 3}]
0赞 brandizzi 1/18/2023
总的来说,这是一个很好的解决方案,但如果你已经有一个库在你的依赖项中做到这一点,那肯定是最好的解决方案。这个答案启发了我在我的依赖项中查找一些东西,瞧,我们已经使用了 lodash,它已经有一个功能。所以,即使它不是同一个库,也感谢您的提醒!uniq()
2赞 Nikola Petkanski 7/12/2012 #5

您还可以使用 jQuery

var a = [1,5,1,6,4,5,2,5,4,3,1,2,6,6,3,3,2,4];

// note: jQuery's filter params are opposite of javascript's native implementation :(
var unique = $.makeArray($(a).filter(function(i,itm){ 
    // note: 'index', not 'indexOf'
    return i == $(a).index(itm);
}));

// unique: [1, 5, 6, 4, 2, 3]

原来回答于: jQuery函数从数组中获取所有唯一元素?

评论

7赞 hippietrail 9/10/2012
这个似乎只适用于整数数组。当我包含一些字符串时,它们都会从结果中剥离出来。
53赞 Mottie 7/12/2012 #6

从那以后,我找到了一个使用jQuery的好方法

arr = $.grep(arr, function(v, k){
    return $.inArray(v ,arr) === k;
});

注意:此代码是从 Paul Irish 的鸭子打孔帖子中提取的 - 我忘了注明:P

评论

12赞 Mister Smith 6/5/2013
一个简洁的解决方案,但调用 inArray 的效率远低于调用 hasOwnProperty。
1赞 speedplane 8/24/2017
这也是 O(N^2),对吧?而字典或 hasOwnProperty 方法可能是 O(N*logN)。
21赞 Gabriel Silveira 7/28/2012 #7

这个原型并不完全正确,因为如果我有一个像这样的数组:它将返回并且是字符串并且是一个整数;他们是不同的。getUnique["1",1,2,3,4,1,"foo"]["1","2","3","4"]"1"1

这是一个正确的解决方案:

Array.prototype.unique = function(a){
    return function(){ return this.filter(a) }
}(function(a,b,c){ return c.indexOf(a,b+1) < 0 });

用:

var foo;
foo = ["1",1,2,3,4,1,"foo"];
foo.unique();

以上将产生.["1",2,3,4,1,"foo"]

评论

3赞 Camilo Martin 6/12/2013
请注意,这是 PHP 声明变量的方式。它将在 javascript 中工作,但会创建一个隐式全局,通常不应该这样做。$foo = 'bar'
1赞 Rob 7/17/2013
@CamiloMartin抱歉,但你错了,$foo是全局的,因为该示例不在闭包中,并且他缺少 var 关键字。与美元无关 jsfiddle.net/robaldred/L2MRb
10赞 Camilo Martin 7/19/2013
@Rob这正是我要说的,PHP 人们会认为这是在 javascript 中声明变量的方式,而实际上却是。$foovar foo
4541赞 TLindig 1/21/2013 #8

JavaScript 1.6 / ECMAScript 5 中,您可以通过以下方式使用 Array 的本机过滤器方法来获取具有唯一值的数组:

function onlyUnique(value, index, array) {
  return array.indexOf(value) === index;
}

// usage example:
var a = ['a', 1, 'a', 2, '1'];
var unique = a.filter(onlyUnique);

console.log(unique); // ['a', 1, 2, '1']

本机方法将遍历数组,只保留那些通过给定回调函数的条目。filteronlyUnique

onlyUnique检查给定值是否是第一个出现的值。否则,它必须是重复的,不会被复制。

此解决方案无需任何额外的库(如jQuery或prototype.js)即可工作。

它也适用于具有混合值类型的数组。

对于不支持本机方法的旧浏览器(<ie9),您可以在 MDN 文档中找到 filterindexOf 的解决方法。filterindexOf

如果要保留值的最后一次出现,只需替换为 。indexOflastIndexOf

在 ES6 中,这可以缩短为:

// usage example:
var myArray = ['a', 1, 'a', 2, '1'];
var unique = myArray.filter((value, index, array) => array.indexOf(value) === index);

console.log(unique); // unique is ['a', 1, 2, '1']

感谢 Camilo Martin 在评论中的提示。

ES6 有一个原生对象 Set 来存储唯一值。要获取具有唯一值的数组,您现在可以这样做:

var myArray = ['a', 1, 'a', 2, '1'];

let unique = [...new Set(myArray)];

console.log(unique); // unique is ['a', 1, 2, '1']

的构造函数采用一个可迭代对象,如 Array,spread 运算符将集合转换回 Array。感谢 Lukas Liese 在评论中的提示。Set...

评论

112赞 Jack Franzen 11/23/2013
不幸的是,此解决方案的运行速度要慢得多。您循环了两次,一次使用过滤器,一次使用索引
51赞 Camilo Martin 7/24/2016
在现代 JS 中:(胖箭头表示法)。.filter((v,i,a)=>a.indexOf(v)==i)
385赞 Lukas Liesis 11/19/2016
let unique_values = [...new Set(random_array)]; developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/......
28赞 Vectorjohn 2/16/2022
为了避免任何新人被性能影响吓跑,考虑一下“慢得多”很可能是纳秒。如果你的数组相对较小(数百个或更少),那么使用像这样简洁的一次性版本是出于性能之外的原因,即可读性和可维护性。但是套装版本相当漂亮和简洁。
22赞 Christian 5/23/2022
比较 Chrome 100 中 .filter+indexOf 和 Set-approach 的性能表明,对于数字和长度为 0 到 120 的数组,filter-approach 甚至更快。当数组长度为 200 时,滤波器方法所需的时间比使用 Set 多 50%(6 微秒与 9 微秒)。对于 5000 个元素,过滤操作需要超过 3 毫秒,而 Set 仍然在 173 微秒内处理我的示例。所以“慢得多”,实际上取决于用例。如果有人有兴趣,我可以将数据作为单独的问答发布。
17赞 Cœur 4/18/2013 #9

无需扩展 Array.prototype(据说这是一种不好的做法)或使用 jquery/underscore,您可以简单地创建数组。filter

通过保留上次出现:

    function arrayLastUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps last occurrence
            return c.indexOf(a, b + 1) < 0;
        });
    },

或首次出现:

    function arrayFirstUnique(array) {
        return array.filter(function (a, b, c) {
            // keeps first occurrence
            return c.indexOf(a) === b;
        });
    },

好吧,它只是javascript ECMAScript 5+,这意味着只有IE9+,但它非常适合在原生HTML/JS中开发(Windows Store App,Firefox OS,Sencha,Phonegap,Titanium等)。

评论

2赞 Camilo Martin 5/23/2013
它是 js 1.6 的事实并不意味着你不能使用 .在 MDN 页面上,他们有一个 Internet Explorer 的实现,我的意思是,较旧的浏览器。另外:JS 1.6 仅指 Firefox 的 js 引擎,但正确的说法是它是 ECMAScript 5。filter
2赞 Torbjörn Nomell 5/23/2013 #10

如果有人使用 knockoutjs

ko.utils.arrayGetDistinctValues()

顺便说一句,已经查看了所有实用程序。ko.utils.array*

8赞 Dan Fox 6/7/2013 #11

我不确定为什么加布里埃尔·西尔维拉(Gabriel Silveira)以这种方式编写函数,但是对于我来说,一种更简单的形式也适用于我,并且没有缩小是:

Array.prototype.unique = function() {
  return this.filter(function(value, index, array) {
    return array.indexOf(value, index + 1) < 0;
  });
};

或在 CoffeeScript 中:

Array.prototype.unique = ->
  this.filter( (value, index, array) ->
    array.indexOf(value, index + 1) < 0
  )
0赞 Kishore Relangi 7/3/2013 #12

如果顺序不重要,那么我们可以进行哈希并获取键以创建唯一数组。

var ar = [1,3,4,5,5,6,5,6,2,1];
var uarEle = {};
links.forEach(function(a){ uarEle[a] = 1; });
var uar = keys(uarEle)

UAR 将具有唯一的数组元素。

7赞 Jason 7/18/2013 #13

看来我们已经失去了拉斐尔的答案,这个答案在几年内一直是公认的答案。如果您没有混合类型数组,这是(至少在 2017 年)性能最好的解决方案:

Array.prototype.getUnique = function(){
    var u = {}, a = [];
    for (var i = 0, l = this.length; i < l; ++i) {
        if (u.hasOwnProperty(this[i])) {
            continue;
        }
        a.push(this[i]);
        u[this[i]] = 1;
    }
return a;
}

如果确实有混合类型的数组,则可以序列化哈希键:

Array.prototype.getUnique = function() {
    var hash = {}, result = [], key; 
    for ( var i = 0, l = this.length; i < l; ++i ) {
        key = JSON.stringify(this[i]);
        if ( !hash.hasOwnProperty(key) ) {
            hash[key] = true;
            result.push(this[i]);
        }
    }
    return result;
}
1赞 kornfridge 7/27/2013 #14

您还可以使用 sugar.js:

[1,2,2,3,1].unique() // => [1,2,3]

[{id:5, name:"Jay"}, {id:6, name:"Jay"}, {id: 5, name:"Jay"}].unique('id') 
  // => [{id:5, name:"Jay"}, {id:6, name:"Jay"}]
3赞 Mrchief 8/16/2013 #15

基于其他答案,这是另一个变体,它采用可选标志来选择策略(保留第一个出现或保留最后):

无需扩展 Array.prototype

function unique(arr, keepLast) {
  return arr.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
unique(['a', 1, 2, '1', 1, 3, 2, 6]); // -> ['a', 1, 2, '1', 3, 6]
unique(['a', 1, 2, '1', 1, 3, 2, 6], true); // -> ['a', '1', 1, 3, 2, 6]

扩展 Array.prototype

Array.prototype.unique = function (keepLast) {
  return this.filter(function (value, index, array) {
    return keepLast ? array.indexOf(value, index + 1) < 0 : array.indexOf(value) === index;
  });
};

// Usage
['a', 1, 2, '1', 1, 3, 2, 6].unique(); // -> ['a', 1, 2, '1', 3, 6]
['a', 1, 2, '1', 1, 3, 2, 6].unique(true); // -> ['a', '1', 1, 3, 2, 6]
-1赞 PaulL 12/7/2013 #16

另一个答案,只是因为我为我的特定用例写了一个答案。无论如何,我碰巧正在对数组进行排序,鉴于我正在排序,我可以使用它来删除重复数据。

请注意,我的排序处理我的特定数据类型,您可能需要不同的排序,具体取决于您拥有的元素类型。

var sortAndDedup = function(array) {
  array.sort(function(a,b){
    if(isNaN(a) && isNaN(b)) { return a > b ? 1 : (a < b ? -1 : 0); }
    if(isNaN(a)) { return 1; }
    if(isNaN(b)) { return -1; }
    return a-b;
  });

  var newArray = [];
  var len = array.length;
  for(var i=0; i<len; i++){
    if(i === 0 || array[i] != array[i-1]){
      newArray.push(array[i]);
    }
  }
};
75赞 Seth Holladay 1/15/2014 #17

这里的许多答案可能对初学者没有用。如果对数组进行重复数据删除很困难,他们真的会了解原型链,甚至 jQuery 吗?

在现代浏览器中,一个干净而简单的解决方案是将数据存储在一个 Set 中,该 Set 被设计为唯一值的列表。

const cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
const uniqueCars = Array.from(new Set(cars));
console.log(uniqueCars);

将 Set 转换回数组很有用,这样你就可以轻松访问数组所具有的所有很棒的方法(功能)。还有其他方法可以做同样的事情。但你可能根本不需要,因为 Sets 有很多有用的功能,比如 forEachArray.fromArray.from

如果您需要支持旧的 Internet Explorer,因此无法使用 Set,那么一个简单的方法是将项目复制到新数组中,同时事先检查它们是否已在新数组中。

// Create a list of cars, with duplicates.
var cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
// Create a list of unique cars, to put a car in if we haven't already.
var uniqueCars = [];

// Go through each car, one at a time.
cars.forEach(function (car) {
    // The code within the following block runs only if the
    // current car does NOT exist in the uniqueCars list
    // - a.k.a. prevent duplicates
    if (uniqueCars.indexOf(car) === -1) {
        // Since we now know we haven't seen this car before,
        // copy it to the end of the uniqueCars list.
        uniqueCars.push(car);
    }
});

为了使它立即可重用,让我们把它放在一个函数中。

function deduplicate(data) {
    if (data.length > 0) {
        var result = [];

        data.forEach(function (elem) {
            if (result.indexOf(elem) === -1) {
                result.push(elem);
            }
        });

        return result;
    }
}

因此,为了摆脱重复项,我们现在将这样做。

var uniqueCars = deduplicate(cars);

当函数完成时,该部件成为我们命名为 result 的东西。deduplicate(cars)

只需将您喜欢的任何数组的名称传递给它即可。

评论

0赞 Jason 6/18/2021
如果我希望新数组不是唯一的数组,而是重复的值数组,这将如何工作?所以使用上面的例子,我正在寻找的数组是["volvo","lincoln"]
0赞 Seth Holladay 6/18/2021
@Jason我可能会创建一个来存储以前看到的项目和一个数组来存储重复的项目。然后遍历数组并检查 Map 是否有当前项目,如果有,则将其推送到 duplicates 数组,如果没有,则将其添加到 Map 中。如果您创建一个新问题,我很乐意为您创建一个代码示例,我们可以在那里继续讨论。Mapcars
0赞 Tranzium 8/19/2022
请注意,如果数组为空,则该函数不会返回任何内容。
0赞 johny why 11/24/2022
太糟糕了,您没有将该方法显示为 array.prototype 的扩展set
0赞 Seth Holladay 8/16/2023
我故意不表现出来。我认为修改是不好的做法,强烈建议不要这样做。除其他原因外,如果将新方法作为语言的一部分添加到 Array 中,可能会导致将来的错误。事实上,如果您的网站很受欢迎,它甚至可以阻止将新方法添加到语言中。这确实发生了。请参见:2ality.com/2022/03/naming-conflicts.htmlArray.prototype
36赞 Joeytje50 1/30/2014 #18

最简单、最快的(在 Chrome 中)方法:

Array.prototype.unique = function() {
    var a = [];
    for (var i=0, l=this.length; i<l; i++)
        if (a.indexOf(this[i]) === -1)
            a.push(this[i]);
    return a;
}

只需遍历数组中的每个项目,测试该项目是否已经在列表中,如果不是,则推送到返回的数组。

根据 JSBench 的说法,这个函数是我在任何地方都能找到的最快的函数 - 不过可以随意添加你自己的函数。

非原型版本:

function uniques(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.push(arr[i]);
    return a;
}

排序

当还需要对数组进行排序时,以下方法是最快的:

Array.prototype.sortUnique = function() {
    this.sort();
    var last_i;
    for (var i=0;i<this.length;i++)
        if ((last_i = this.lastIndexOf(this[i])) !== i)
            this.splice(i+1, last_i-i);
    return this;
}

或非原型:

function sortUnique(arr) {
    arr.sort();
    var last_i;
    for (var i=0;i<arr.length;i++)
        if ((last_i = arr.lastIndexOf(arr[i])) !== i)
            arr.splice(i+1, last_i-i);
    return arr;
}

这也比大多数非 Chrome 浏览器中的上述方法更快

评论

0赞 Adam Katz 2/7/2017
在 Linux 上,Chrome 55.0.2883 更喜欢你的 arr.unique(),而 swilliams 的 arrclone2.sortFilter() 最慢(慢 78%)。然而,Firefox 51.0.0(有很多插件)的 swilliams 最快(但仍然比任何其他 Chrome 结果慢 Ops/sec),mottie 的 jQuery $.grep(arr, jqFilter) 最慢(慢 46%)。您的 arr.uniq() 速度慢了 30%。我每次测试都运行了两次,并得到了一致的结果。Rafael 的 arr.getUnique() 在两个浏览器中都获得了第二名。
0赞 Adam Katz 2/7/2017
jsPerf 目前有问题,所以我对此测试的编辑并没有提交所有内容,但它确实导致添加了两个测试:Cocco 的 toUnique() 在两个浏览器上都击败了 Vamsi 的 ES6 list.filter(),在 FF 上击败了 #1 的 swilliams 的 sortFilter()(sortFilter 慢了 16%),在 Chrome 上击败了 #2% 的排序测试(慢了 3%)。
0赞 Adam Katz 2/7/2017
啊,我没有发现这些测试是微不足道的,并不重要。对已接受答案的注释描述了该问题,并在测试的修订版中提供了更正,其中 Rafael 的代码很容易是最快的,而 Joetje50 的 arr.unique 代码慢了 98%。如本评论所述,我还进行了另一次修订。
7赞 Mikhail Dudin 11/14/2018
好吧,实际上您在函数中实现的算法具有 O(n^2) 复杂度,而 中的算法是 O(n)。第一个在小数据集上可能更快,但你怎么能与数学:)争论如果你在一个数组上运行它,比如说,1e5 个唯一项目,你可以确保后者更快uniquegetUnique
0赞 milahu 9/30/2020
也被 lodash.uniq 用于 ,否则使用该方法。表示为减速器:input_array.length < 200[...new Set(input_array)]input_array.reduce((c, v) => {if (!c.includes(v)) c.push(v); return c;}, [])
0赞 Roobie Nuby 2/23/2014 #19

我在 jsperf 上查看了 Joeytje50 的代码,他比较了许多替代方案。他的代码有许多小错别字,这在性能和正确性方面产生了差异。

更重要的是,他正在一个非常小的阵列上进行测试。我做了一个有 1000 个整数的数组。每个整数是 0 到 1000 之间的随机整数的 100 倍。平均而言,大约有 1000/e = 368 个重复项。结果位于 jsperf

这是一个更现实的场景,可能需要提高效率。这些更改使声明发生了巨大的变化(特别是被吹捧为最快的代码远不及快速)。明显的赢家是使用哈希技术的地方,最好的是

Array.prototype.getUnique3 = function(){
   var u = Object.create(null), a = [];
   for(var i = 0, l = this.length; i < l; ++i){
      if(this[i] in u) continue;
      a.push(this[i]);
      u[this[i]] = 1;
   }
   return a.length;
}
1赞 pix 9/16/2014 #20

这是堆的另一种解决方案。

我最近需要使排序列表唯一,我使用过滤器来跟踪对象中的前一项,如下所示:

uniqueArray = sortedArray.filter(function(e) { 
    if(e==this.last) 
      return false; 
    this.last=e; return true;  
  },{last:null});
25赞 sergeyz 9/20/2014 #21
["Defects", "Total", "Days", "City", "Defects"].reduce(function(prev, cur) {
  return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
 }, []);

[0,1,2,0,3,2,1,5].reduce(function(prev, cur) {
  return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev;
 }, []);

评论

0赞 Alonso Urbano 10/25/2022
这在对象数组中效果很好![].reduce((p, c) => (p.some((item) => c.id === item.id) ? p : p.concat(c)), [])
-1赞 GibboK 3/10/2015 #22

此脚本修改数组,过滤掉重复的值。它适用于数字和字符串。

https://jsfiddle.net/qsdL6y5j/1/

    Array.prototype.getUnique = function () {
        var unique = this.filter(function (elem, pos) {
            return this.indexOf(elem) == pos;
        }.bind(this));
        this.length = 0;
        this.splice(0, 0, unique);
    }

    var duplicates = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    duplicates.getUnique();
    alert(duplicates);

相反,这个版本允许你返回一个具有唯一值的新数组,保留原始值(只需传递 true)。

https://jsfiddle.net/dj7qxyL7/

    Array.prototype.getUnique = function (createArray) {
        createArray = createArray === true ? true : false;
        var temp = JSON.stringify(this);
        temp = JSON.parse(temp);
        if (createArray) {
            var unique = temp.filter(function (elem, pos) {
                return temp.indexOf(elem) == pos;
            }.bind(this));
            return unique;
        }
        else {
            var unique = this.filter(function (elem, pos) {
                return this.indexOf(elem) == pos;
            }.bind(this));
            this.length = 0;
            this.splice(0, 0, unique);
        }
    }

    var duplicates = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    console.log('++++ ovveride')
    duplicates.getUnique();
    console.log(duplicates);
    console.log('++++ new array')
    var duplicates2 = [0, 0, 1, 1, 2, 3, 1, 1, 0, 4, 4];
    var unique = duplicates2.getUnique(true);
    console.log(unique);
    console.log('++++ original')
    console.log(duplicates2);

Browser support:

Feature Chrome  Firefox (Gecko)     Internet Explorer   Opera   Safari
Basic support   (Yes)   1.5 (1.8)   9                   (Yes)   (Yes)

评论

0赞 Nicholas 12/20/2017
在第一条评论中,你为什么要添加和?这还不够吗?this.length = 0;this.splice(0, 0, unique);Array.prototype.uniques = function() { return this.filter(function(value, index){ return this.indexOf(value) === index; }.bind(this)); };
4赞 rab 3/29/2015 #23

使用对象键制作唯一数组,我尝试过以下

function uniqueArray( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });


  return Object.keys(j).map(function(v){
    return j[v];
  });
}   

uniqueArray(["1",1,2,3,4,1,"foo", false, false, null,1]);

哪个返回["1", 1, 2, 3, 4, "foo", false, null]

评论

1赞 Max Makhrov 3/27/2017
我认为,您的答案是最快的解决方案,因为它使用哈希。
2赞 ilgam 4/21/2015 #24

看看这个。Jquery 提供了 uniq 方法:https://api.jquery.com/jQuery.unique/

var ids_array = []

$.each($(my_elements), function(index, el) {
    var id = $(this).attr("id")
    ids_array.push(id)
});

var clean_ids_array = jQuery.unique(ids_array)

$.each(clean_ids_array, function(index, id) {
   elment = $("#" + id)   // my uniq element
   // TODO WITH MY ELEMENT
});

评论

1赞 Mottie 4/22/2015
如果您阅读了链接页面上的描述: 描述:对 DOM 元素数组进行就地排序,并删除重复项。请注意,这仅适用于 DOM 元素的数组,而不适用于字符串或数字。
1赞 Grozz 9/19/2015 #25

接受选择器的版本应该非常快速和简洁:

function unique(xs, f) {
  var seen = {};
  return xs.filter(function(x) {
    var fx = (f && f(x)) || x;
    return !seen[fx] && (seen[fx] = 1);
  });
}
1801赞 A.T. 10/14/2015 #26

ES6/ES2015 的更新答案:使用 Setspread 运算符(感谢 le-m),单行解决方案为:

let uniqueItems = [...new Set(items)]

哪个返回

[4, 5, 6, 3, 2, 23, 1]

评论

24赞 Alexander Goncharov 10/24/2016
请注意,内部数组不起作用Array.from(new Set([[1,2],[1,2],[1,2,3]]))
114赞 mortb 4/5/2017
请注意,如果使用 和 add 对象而不是基元值,它将包含对对象的唯一引用。因此,集合将返回以下内容:这是对包含相同值的对象的唯一对象引用。如果你编写并创建一个包含两个引用的集合,如下所示: ,那么 s2 将是Setslet s = new Set([{Foo:"Bar"}, {Foo:"Bar"}]);Set { { Foo: 'Bar' }, { Foo: 'Bar' } }Setlet o = {Foo:"Bar"};let s2 = new Set([o,o]);Set { { Foo: 'Bar' } }
6赞 Marquez 11/25/2021
如果有人想知道,这也适用于字符串,例如 [...new Set([“apple”,“apple”,“orange”])] 的结果为 ['apple', 'orange'] 。伟大!
0赞 Lee Goddard 5/23/2022
在 Typescript 中,使用Array.from( new Set( items ) )
1赞 webdeb 11/4/2015 #27

这个不纯,它会修改数组,但这是最快的。如果你的更快,那么请在评论中写下;)

http://jsperf.com/unique-array-webdeb

Array.prototype.uniq = function(){
    for(var i = 0, l = this.length; i < l; ++i){
        var item = this[i];
        var duplicateIdx = this.indexOf(item, i + 1);
        while(duplicateIdx != -1) {
            this.splice(duplicateIdx, 1);
            duplicateIdx = this.indexOf(item, duplicateIdx);
            l--;
        }
    }

    return this;
}

[
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc",
 "",2,4,"A","abc"
].uniq() //  ["",2,4,"A","abc"]
1赞 rajesh 11/19/2015 #28
var a = [1,4,2,7,1,5,9,2,4,7,2]
var b = {}, c = {};
var len = a.length;
for(var i=0;i<len;i++){
  a[i] in c ? delete b[a[i]] : b[a[i]] = true;
  c[a[i]] = true;
} 

// b contains all unique elements

评论

0赞 Mottie 11/20/2015
b在上面的示例(演示)中返回。{5: true, 9: true}
7赞 Saravanan Rajaraman 1/7/2016 #29

在简单方法中查找唯一的 Array 值

function arrUnique(a){
  var t = [];
  for(var x = 0; x < a.length; x++){
    if(t.indexOf(a[x]) == -1)t.push(a[x]);
  }
  return t;
}
arrUnique([1,4,2,7,1,5,9,2,4,7,2]) // [1, 4, 2, 7, 5, 9]

评论

0赞 Pooja Thapa 11/10/2020
这个答案怎么可能正确?根据给定的输入 [1,4,2,7,1,5,9,2,4,7,2] 的唯一数组的预期结果为 [5,9]
0赞 Saravanan Rajaraman 8/22/2022
@PoojaThapa这将从输入数组中提取唯一值。
145赞 Vamsi 9/1/2016 #30

One Liner,纯 JavaScript

使用 ES6 语法

list = list.filter((x, i, a) => a.indexOf(x) == i)

x --> item in array
i --> index of item
a --> array reference, (in this case "list")

enter image description here

使用 ES5 语法

list = list.filter(function (x, i, a) { 
    return a.indexOf(x) == i; 
});

浏览器兼容性:IE9+

0赞 pgee70 11/11/2016 #31

我知道这已经被回答得死去活来......但。。。 没有人提到 LINQ 的 JavaScript 实现。 然后可以使用该方法 - 它使代码超级易于阅读。.distinct()

var Linq = require('linq-es2015');
var distinctValues =  Linq.asEnumerable(testValues)
            .Select(x)
            .distinct()
            .toArray();

var testValues = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1];

var distinctValues = Enumerable.asEnumerable(testValues)
  .distinct()
  .toArray();

console.log(distinctValues);
<script src="https://npmcdn.com/linq-es5/dist/linq.js"></script>

1赞 Leonardo 1/6/2017 #32

对于字符串数组:

function removeDuplicatesFromArray(arr) {
  const unique = {};
  arr.forEach((word) => {
    unique[word] = 1; // it doesn't really matter what goes here
  });
  return Object.keys(unique);
}

评论

0赞 Sahith Vibudhi 12/11/2019
为什么这个答案被否决了?它确实按预期工作!
0赞 peter_the_oak 4/6/2021
谢谢。这也是我在这里作为单行方法的方法,作为带有重复项的数组和辅助数组:我喜欢使用对象的内部哈希表。ahvar h = {}; for (var k in a) { h[a[k]] = true;}; var unique = Object.keys(h);
-2赞 bvmCoder 1/9/2017 #33

(function() {
    "use strict";

    Array.prototype.unique = function unique() {
        var self = this;
        return self.filter(function(a) {
            var that = this;
            // console.log(that);
            return !that[a] ? that[a] = true : false;
        }, {});
    }

    var sampleArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    var distinctArray = sampleArray.unique();
    console.log(distinctArray);
})();
Here is the simple way to solve this problem...

0赞 Ben 2/24/2017 #34

如果你有一个对象数组,并且你想要一个函数,比如说,通过一个 id 字段:uniqueBy

function uniqueBy(field, arr) {
   return arr.reduce((acc, curr) => {
     const exists = acc.find(v => v[field] === curr[field]);
     return exists ? acc : acc.concat(curr);
   }, [])
}
346赞 Max Makhrov 3/27/2017 #35

我将所有答案拆分为 4 种可能的解决方案:

  1. 使用对象防止重复{ }
  2. 使用帮助程序数组[ ]
  3. filter + indexOf
  4. 奖金!ES6 方法。Sets

以下是在答案中找到的示例代码:

使用对象防止重复{ }

function uniqueArray1( ar ) {
  var j = {};

  ar.forEach( function(v) {
    j[v+ '::' + typeof v] = v;
  });

  return Object.keys(j).map(function(v){
    return j[v];
  });
} 

使用帮助程序数组[ ]

function uniqueArray2(arr) {
    var a = [];
    for (var i=0, l=arr.length; i<l; i++)
        if (a.indexOf(arr[i]) === -1 && arr[i] !== '')
            a.push(arr[i]);
    return a;
}

filter + indexOf

function uniqueArray3(a) {
  function onlyUnique(value, index, self) { 
      return self.indexOf(value) === index;
  }

  // usage
  var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1']

  return unique;
}

使用 ES6 [...new Set(a)]

function uniqueArray4(a) {
  return [...new Set(a)];
}

我想知道哪个更快。我制作了示例 Google 表格来测试功能。注意:ECMA 6 在 Google 表格中不可用,因此我无法对其进行测试。

以下是测试结果:enter image description here

我希望看到使用 object 的代码会获胜,因为它使用哈希。因此,我很高兴测试显示了该算法在 Chrome 和 IE 中的最佳结果。感谢 @rab 的代码{ }

更新 2020

启用了 Google Script ES6 引擎。现在我测试了最后一个代码,它比 object 方法出现得更快。Sets

评论

11赞 Vass 10/30/2021
马克罗夫,所以这似乎是所有方法中最快、最简洁的?uniqueItems = [...new Set(items)]
1赞 Tofandel 5/4/2022
你的解决方案只处理基元,它不适用于对象,你需要对哈希中的 v 进行 JSON.string化
3赞 João Pimentel Ferreira 8/23/2022
你非常适合进行这次测试比较,谢谢,我现在用一个包含数十万个条目的数组进行了测试,而且看起来确实是最快的uniqueItems = [...new Set(items)]
0赞 Taylor Allred 8/8/2023
“Object.keys(j).map ...”可以更改为使用Object.values(j);
0赞 Ali 9/3/2017 #36

使用 field[2] 作为 Id 创建唯一数组的数组:

const arr = [
  ['497', 'Q0', 'WTX091-B06-138', '0', '1.000000000', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B09-92', '1', '0.866899288', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B09-92', '2', '0.846036819', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B09-57', '3', '0.835025326', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B43-79', '4', '0.765068215', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B43-56', '5', '0.764211464', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B44-448', '6', '0.761701704', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B44-12', '7', '0.761701704', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B49-128', '8', '0.747434800', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B18-17', '9', '0.746724770', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B19-374', '10', '0.733379549', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B19-344', '11', '0.731421782', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B09-92', '12', '0.726450470', 'GROUP001'],
  ['497', 'Q0', 'WTX091-B19-174', '13', '0.712757036', 'GROUP001']
];


arr.filter((val1, idx1, arr) => !!~val1.indexOf(val1[2]) &&
  !(arr.filter((val2, idx2) => !!~val2.indexOf(val1[2]) &&
    idx2 < idx1).length));

console.log(arr);

0赞 Andrei 10/27/2017 #37

这是一个 ES6 函数,它从对象数组中删除重复项,并按指定的对象属性进行过滤

function dedupe(arr = [], fnCheck = _ => _) {
  const set = new Set();
  let len = arr.length;

  for (let i = 0; i < len; i++) {
    const primitive = fnCheck(arr[i]);
    if (set.has(primitive)) {
      // duplicate, cut it
      arr.splice(i, 1);
      i--;
      len--;
    } else {
      // new item, add it
      set.add(primitive);
    }
  }

  return arr;
}

const test = [
    {video:{slug: "a"}},
    {video:{slug: "a"}},
    {video:{slug: "b"}},
    {video:{slug: "c"}},
    {video:{slug: "c"}}
]
console.log(dedupe(test, x => x.video.slug));

// [{video:{slug: "a"}}, {video:{slug: "b"}}, {video:{slug: "c"}}]
6赞 daviestar 2/2/2018 #38

奇怪的是,这以前没有被建议过。要通过数组中的对象键(如下)删除重复项,您可以执行如下操作:id

const uniqArray = array.filter((obj, idx, arr) => (
  arr.findIndex((o) => o.id === obj.id) === idx
)) 

评论

0赞 Adam Katz 11/26/2019
不是两者兼而有之,必须遍历数组?这将使它成为一个双循环,因此运行成本是任何其他答案的两倍。filter()findIndex()
0赞 daviestar 11/27/2019
@AdamKatz是的,它将遍历数组 n+1 次。请注意,这里使用map,filter,indexOf,reduce等组合的其他答案也必须这样做,这是问题固有的。为了避免这种情况,您可以使用 ,或者类似于 Grozz 的答案的查找对象。new Set()
37赞 chinmayan 4/9/2018 #39

我们可以使用 ES6 集合来做到这一点:

var duplicatesArray = [1, 2, 3, 4, 5, 1, 1, 1, 2, 3, 4];
var uniqueArray = [...new Set(duplicatesArray)];

console.log(uniqueArray); // [1,2,3,4,5]

10赞 NikeshPathania 6/11/2018 #40

如果您对额外的依赖项感到满意,或者您的代码库中已经有一个库,则可以使用 LoDash(或下划线)从数组中删除重复项。

用法

如果代码库中还没有它,请使用 npm 安装它:

npm install lodash

然后按如下方式使用它:

import _ from 'lodash';
let idArray = _.uniq ([
    1,
    2,
    3,
    3,
    3
]);
console.dir(idArray);

外:

[ 1, 2, 3 ]

评论

0赞 Mike 11/21/2020
您还可以使用 lodash 从数组中删除具有重复属性的对象: 。_.uniqWith(objectArray, _.isEqual)
1赞 Morris S 6/27/2018 #41

您可以使用 Ramda.js,一个函数式 javascript 库来执行此操作:

var unique = R.uniq([1, 2, 1, 3, 1, 4])
console.log(unique)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

2赞 BazSTR 7/13/2018 #42

使用 lodash 和 identity lambda 函数来做到这一点,只需在使用对象之前定义它即可

const _ = require('lodash');
...    
_.uniqBy([{a:1,b:2},{a:1,b:2},{a:1,b:3}], v=>v.a.toString()+v.b.toString())
_.uniq([1,2,3,3,'a','a','x'])

并将有:

[{a:1,b:2},{a:1,b:3}]
[1,2,3,'a','x']

(这是最简单的方法)

0赞 tjacks3 8/23/2018 #43

我有一个使用 es6 reduce 和 find 数组帮助程序方法来删除重复项的解决方案。

let numbers = [2, 2, 3, 3, 5, 6, 6];

const removeDups = array => {
  return array.reduce((acc, inc) => {
    if (!acc.find(i => i === inc)) {
      acc.push(inc);
    }
    return acc;
  }, []);
}

console.log(removeDups(numbers)); /// [2,3,5,6]

12赞 shunryu111 10/11/2018 #44

我遇到了一个稍微不同的问题,我需要从数组中删除具有重复 id 属性的对象。这奏效了。

let objArr = [{
  id: '123'
}, {
  id: '123'
}, {
  id: '456'
}];

objArr = objArr.reduce((acc, cur) => [
  ...acc.filter((obj) => obj.id !== cur.id), cur
], []);

console.log(objArr);

51赞 Kamil Kiełczewski 11/29/2018 #45

魔法

a.filter( e => !(t[e]=e in t) ) 

O(n) 性能 - 我们假设您的数组位于 和 中。解释在这里 (+Jeppe impr.)at={}

let unique = (a,t={}) => a.filter(e=>!(t[e]=e in t));

// "stand-alone" version working with global t:
// a1.filter((t={},e=>!(t[e]=e in t)));

// Test data
let a1 = [5,6,0,4,9,2,3,5,0,3,4,1,5,4,9];
let a2 = [[2, 17], [2, 17], [2, 17], [1, 12], [5, 9], [1, 12], [6, 2], [1, 12]];
let a3 = ['Mike', 'Adam','Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl'];

// Results
console.log(JSON.stringify( unique(a1) ))
console.log(JSON.stringify( unique(a2) ))
console.log(JSON.stringify( unique(a3) ))

评论

75赞 Ondřej Želazko 1/8/2019
这看起来非常酷,以至于没有可靠的解释,我摔倒了,当我运行它时,你会开采比特币
5赞 Ondřej Želazko 1/9/2019
我的意思是,你应该用一些解释来扩展你的答案,并评论解构它。不要指望人们会找到这样有用的答案。(虽然它看起来真的很酷,但可能有效)
2赞 Jeppe 1/14/2019
不是魔术,但很像“Set”答案,使用字典中的 O(1) 键查找。但是,您需要增加计数器吗?“e=>怎么样!(t[e]=e in t)”。不过不错的答案。
2赞 Kamil Kiełczewski 1/14/2019
@Jeppe当我运行您的改进时,我会遇到 aha 效果(在我不知道我可以在循环 :P 之外使用其他结构之外的运算符) - 谢谢 - 我很感激,并会给您的其他好答案 +2。infor
2赞 Max Starling 10/22/2022
好吧,解决方案确实很棒 但是它仅适用于元组 以下示例工作不正确: 所以要小心unique(['2', 2]) // ['2'];unique([[1, 7], [1, '7'], ['1', 7], ['1', '7']]) // [1, 7]
0赞 user3591464 11/29/2018 #46

上面的对象答案在我对对象的用例中似乎对我不起作用。

我修改如下:

var j = {};

this.forEach( function(v) {
   var typ = typeof v;
   var v = (typ === 'object') ? JSON.stringify(v) : v;

   j[v + '::' + typ] = v;
});

return Object.keys(j).map(function(v){
  if ( v.indexOf('::object') > -1 ) {
    return JSON.parse(j[v]);
  }

  return j[v];
});

现在,这似乎适用于对象、数组、具有混合值的数组、布尔值等。

0赞 Junaid Khan 12/12/2018 #47

var numbers = [1, 1, 2, 3, 4, 4];

function unique(dupArray) {
  return dupArray.reduce(function(previous, num) {

    if (previous.find(function(item) {
        return item == num;
      })) {
      return previous;
    } else {
      previous.push(num);
      return previous;
    }
  }, [])
}

var check = unique(numbers);
console.log(check);

0赞 LEMUEL ADANE 2/15/2019 #48

筛选出未定义的值和 null 值,因为大多数时候您不需要它们。

const uniques = myArray.filter(e => e).filter((e, i, a) => a.indexOf(e) === i);

const uniques = [...new Set(myArray.filter(e => e))];
0赞 Nidhal Ben Tahar 2/18/2019 #49

有时我需要从对象数组中获取唯一实例。Lodash 似乎是一个不错的帮手,但我不认为过滤数组可以证明向项目添加依赖项是合理的。

让我们假设两个对象的比较在比较一个属性(例如 id)时摆出姿势。

const a = [{id: 3}, {id: 4}, {id: 3}, {id: 5}, {id: 5}, {id: 5}];

由于我们都喜欢一行片段,因此可以这样做:

a.reduce((acc, curr) => acc.find(e => e.id === curr.id) ? acc : [...acc, curr], [])

0赞 Firas Abd Alrahman 4/9/2019 #50

此解决方案应该非常快,并且在许多情况下都有效。

  1. 将索引数组项转换为对象键
  2. 使用 Object.keys 函数

    var indexArray = ["hi","welcome","welcome",1,-9];
    var keyArray = {};
    indexArray.forEach(function(item){ keyArray[item]=null; });
    var uniqueArray = Object.keys(keyArray);
    
0赞 Shridhar Sagari 5/10/2019 #51

我有一个简单的例子,我们可以从数组中删除对象,这些对象在对象中具有重复的 id,

  let data = new Array({id: 1},{id: 2},{id: 3},{id: 1},{id: 3});
  let unique = [];
  let tempArr = [];
  console.log('before', data);
  data.forEach((value, index) => {
    if (unique.indexOf(value.id) === -1) {
      unique.push(value.id);
    } else {
      tempArr.push(index);    
    }
  });
  tempArr.reverse();
  tempArr.forEach(ele => {
    data.splice(ele, 1);
  });
  console.log(data);
14赞 Krishnadas PC 5/17/2019 #52

现在使用集合,您可以删除重复项并将它们转换回数组。

var names = ["Mike","Matt","Nancy", "Matt","Adam","Jenny","Nancy","Carl"];

console.log([...new Set(names)])

另一种解决方案是使用排序和过滤

var names = ["Mike","Matt","Nancy", "Matt","Adam","Jenny","Nancy","Carl"];
var namesSorted = names.sort();
const result = namesSorted.filter((e, i) => namesSorted[i] != namesSorted[i+1]);
console.log(result);

1赞 Nizmox 7/3/2019 #53

很多人已经提到使用...

[...new Set(arr)];

这是一个很好的解决方案,但我更喜欢与 .在我看来,过滤器是获取唯一值的一种更自然的方式。您有效地删除了重复项,而从数组中删除元素正是过滤器的用途。它还允许您链接 、 和其他调用。我设计了这个解决方案.......filter.map.reduce.filter

const unique = () => {
  let cache;  
  return (elem, index, array) => {
    if (!cache) cache = new Set(array);
    return cache.delete(elem);
  };
};

myArray.filter(unique());

需要注意的是,你需要一个闭包,但我认为这是一个值得的权衡。在性能方面,它比我看到的其他解决方案性能更高,但性能比 差。.filter[...new Set(arr)]

参见我的 github 包 youneek

2赞 user5536315 7/15/2019 #54

重复数据删除通常需要给定类型的相等运算符。但是,使用函数会阻止我们有效地利用 a 来确定重复项,因为回退到 .如您所知,不适用于引用类型。所以如果被困住了,我们是善良的,对吧?eqSetSet======

出路很简单,就是使用一个转换器函数,它允许我们将一个(引用)类型转换为我们可以使用 .例如,我们可以使用哈希函数或数据结构,如果它不包含任何函数。SetJSON.stringify

通常,我们只需要访问一个属性,然后我们可以比较该属性而不是 的引用。Object

以下是满足这些要求的两个组合器:

const dedupeOn = k => xs => {
  const s = new Set();

  return xs.filter(o =>
    s.has(o[k])
      ? null
      : (s.add(o[k]), o[k]));
};

const dedupeBy = f => xs => {
  const s = new Set();

  return xs.filter(x => {
    const r = f(x);
    
    return s.has(r)
      ? null
      : (s.add(r), x);
  });
};

const xs = [{foo: "a"}, {foo: "b"}, {foo: "A"}, {foo: "b"}, {foo: "c"}];

console.log(
  dedupeOn("foo") (xs)); // [{foo: "a"}, {foo: "b"}, {foo: "A"}, {foo: "c"}]

console.log(
  dedupeBy(o => o.foo.toLowerCase()) (xs)); // [{foo: "a"}, {foo: "b"}, {foo: "c"}]

有了这些组合器,我们可以非常灵活地处理各种重复数据删除问题。这不是斋戒方法,而是最具表现力和最通用的方法。

18赞 ifelse.codes 7/19/2019 #55
[...new Set(duplicates)]

这是最简单的一个,引用自 MDN Web Docs

const numbers = [2,3,4,4,2,3,3,4,4,5,5,6,6,7,5,32,3,4,5]
console.log([...new Set(numbers)]) // [2, 3, 4, 5, 6, 7, 32]

评论

1赞 id.ot 7/20/2019
虽然这段代码可能会解决这个问题,但包括解释它如何以及为什么解决这个问题将真正有助于提高你的帖子的质量,并可能导致更多的赞成票。请记住,您是在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释,并指出适用哪些限制和假设。
1赞 vsync 6/21/2022
之前的答案相同,日期比这个答案早一年
24赞 Dave 9/6/2019 #56

这个问题已经得到了很多回答,但它并没有满足我的特殊需求。

很多答案是这样的:

a.filter((item, pos, self) => self.indexOf(item) === pos);

但这不适用于复杂对象的数组。

假设我们有一个这样的数组:

const a = [
 { age: 4, name: 'fluffy' },
 { age: 5, name: 'spot' },
 { age: 2, name: 'fluffy' },
 { age: 3, name: 'toby' },
];

如果我们想要具有唯一名称的对象,我们应该使用而不是:array.prototype.findIndexarray.prototype.indexOf

a.filter((item, pos, self) => self.findIndex(v => v.name === item.name) === pos);

评论

1赞 Thanwa Ch. 4/3/2020
很好的解决方案,请注意新数组将从函数返回。(它不会自行修改)
0赞 Edgar Quintero 12/15/2020
作品将与一系列复杂的物品一起使用
1赞 Dave 12/15/2020
仅当元素实际上是完全相同的对象时才@EdgarQuintero,因此,如果您使用该解决方案,数组 [ { a: 2 }, { a: 2 } ] 将不会像许多人预期的那样工作,但该解决方案可能很有用indexOffindIndex
-1赞 Nikki Luzader 10/9/2019 #57

你可以试试这个:

function removeDuplicates(arr){
  var temp = arr.sort();
  for(i = 0; i < temp.length; i++){
    if(temp[i] == temp[i + 1]){
      temp.splice(i,1);
      i--;
    }
  }
  return temp;
}
1赞 noor 10/19/2019 #58

如果您只想获取唯一元素并删除重复一次的元素,则可以这样做:

let array = [2, 3, 4, 1, 2, 8, 1, 1, 2, 9, 3, 5, 3, 4, 8, 4];

function removeDuplicates(inputArray) {
  let output = [];
  let countObject = {};

  for (value of array) {
    countObject[value] = (countObject[value] || 0) + 1;
  }

  for (key in countObject) {
    if (countObject[key] === 1) {
      output.push(key);
    }
  }

  return output;
}

console.log(removeDuplicates(array));

1赞 WesleyAC 11/16/2019 #59

你根本不需要 .indexOf();你可以这样做 O(n):

function SelectDistinct(array) {
    const seenIt = new Set();

    return array.filter(function (val) {
        if (seenIt.has(val)) { 
            return false;
        }

        seenIt.add(val);

        return true;
    });
}

var hasDuplicates = [1,2,3,4,5,5,6,7,7];
console.log(SelectDistinct(hasDuplicates)) //[1,2,3,4,5,6,7]

如果您不想使用 .filter():

function SelectDistinct(array) {
    const seenIt = new Set();
    const distinct = [];

    for (let i = 0; i < array.length; i++) {
        const value = array[i];

        if (!seenIt.has(value)) {
            seenIt.add(value);
            distinct.push(value);
        }
    }
    
    return distinct; 
    /* you could also drop the 'distinct' array and return 'Array.from(seenIt)', which converts the set object to an array */
}
0赞 user11722559 1/24/2020 #60

最简单的方法是将值转换为字符串,以筛选嵌套对象值。

const uniq = (arg = []) => {
  const stringifyedArg = arg.map(value => JSON.stringify(value))
  return arg.filter((value, index, self) => {
    if (typeof value === 'object')
      return stringifyedArg.indexOf(JSON.stringify(value)) === index
    return self.indexOf(value) === index
  })
}

    console.log(uniq([21, 'twenty one', 21])) // [21, 'twenty one']
    console.log(uniq([{ a: 21 }, { a: 'twenty one' }, { a: 21 }])) // [{a: 21}, {a: 'twenty one'}]
5赞 Shreyansh Sharma 2/29/2020 #61

对于具有一些唯一 id 的基于对象的数组,我有一个简单的解决方案,您可以通过它按线性复杂度进行排序

function getUniqueArr(arr){
    const mapObj = {};
    arr.forEach(a => { 
       mapObj[a.id] = a
    })
    return Object.values(mapObj);
}
4赞 Roman 7/1/2020 #62

任务是从由任意类型(原始和非原始)组成的数组中获取唯一的数组。

基于使用的方法并不新鲜。这里利用了 和 方法。优点是通用性(适用于任何类型的数组)、简短的 ES6 符号以及在这种情况下可能的性能new Set(...)JSON.stringify(...)JSON.parse(...)[].map

const dedupExample = [
    { a: 1 },
    { a: 1 },
    [ 1, 2 ],
    [ 1, 2 ],
    1,
    1,
    '1',
    '1'
]

const getUniqArrDeep = arr => {
    const arrStr = arr.map(item => JSON.stringify(item))
    return [...new Set(arrStr)]
        .map(item => JSON.parse(item))
}

console.info(getUniqArrDeep(dedupExample))
   /* [ {a: 1}, [1, 2], 1, '1' ] */

评论

0赞 airtonix 5/13/2022
由于您正在字符串化然后重新解析,因此积极的性能绝对不是这里的属性。
0赞 Roman 5/13/2022
“积极的表现”和“这里的属性”是什么意思?需要一些详细说明。
0赞 airtonix 5/17/2022
显然,字符串化一个对象,然后再次解析它是你在 JS 中可以做的最昂贵的操作之一。jsben.ch/wQ9RU
0赞 Roman 5/18/2022
@airtonix,确实,我们需要考虑性能。有些情况就像“艰难时期需要艰难的决定”:-)
1赞 Didier68 7/2/2020 #63

在我的解决方案中,我在过滤之前对数据进行排序:

const uniqSortedArray = dataArray.sort().filter((v, idx, t) => idx==0 || v != t[idx-1]); 
23赞 vsync 10/4/2020 #64

在查看了这里所有 90+ 个答案后,我发现还有一个空间:

Array.includes 有一个非常方便的第二个参数:“fromIndex”,因此通过使用它,回调方法的每次迭代都将搜索数组,从该数组开始保证在查找中不包含当前过滤的项目,并且还可以节省时间。filter[current index] + 1

注意 - 此解决方案不保留顺序,因为它从左到右删除了重复的项目,但如果数组对象的集合,则它胜出。Set

//                🚩              🚩 🚩
var list = [0,1,2,2,3,'a','b',4,5,2,'a']

console.log( 
  list.filter((v,i) => !list.includes(v,i+1))
)

// [0,1,3,"b",4,5,2,"a"]

解释:

例如,假设该函数当前正在迭代索引 ),而该索引处的值恰好是 。然后扫描重复项的数组部分(方法)是索引 2 () 之后的所有内容:filter22includesi+1

           👇                    👇
[0, 1, 2,   2 ,3 ,'a', 'b', 4, 5, 2, 'a']
       👆   |---------------------------|

由于当前筛选项的值包含在数组的其余部分,因此它将被过滤掉,因为前导感叹号否定了过滤规则。2


如果顺序很重要,请使用以下方法:

//                🚩              🚩 🚩
var list = [0,1,2,2,3,'a','b',4,5,2,'a']

console.log( 
  // Initialize with empty array and fill with non-duplicates
  list.reduce((acc, v) => (!acc.includes(v) && acc.push(v), acc), [])
)

// [0,1,2,3,"a","b",4,5]

评论

0赞 lapo 12/15/2020
不幸的是,这会保留每个值的最后一个实例,而不是第一个实例。(这可能没问题,但我认为保留第一个通常是预期的)
0赞 minhtus 6/21/2022
虽然这是一个很好的优化想法,但我认为人们不会想要使用它,因为这保留了最后一项,这基本上会扰乱数组顺序。
3赞 nkitku 10/23/2020 #65

使用 One Liner 在对象数组中查找唯一值

const uniqueBy = (x,f)=>Object.values(x.reduce((a,b)=>((a[f(b)]=b),a),{}));
// f -> should must return string because it will be use as key

const data = [
  { comment: "abc", forItem: 1, inModule: 1 },
  { comment: "abc", forItem: 1, inModule: 1 },
  { comment: "xyz", forItem: 1, inModule: 2 },
  { comment: "xyz", forItem: 1, inModule: 2 },
];

uniqueBy(data, (x) => x.forItem +'-'+ x.inModule); // find unique by item with module
// output
// [
//   { comment: "abc", forItem: 1, inModule: 1 },
//   { comment: "xyz", forItem: 1, inModule: 2 },
// ];

// can also use for strings and number or other primitive values

uniqueBy([1, 2, 2, 1], (v) => v); // [1, 2]
uniqueBy(["a", "b", "a"], (v) => v); // ['a', 'b']

uniqueBy(
  [
    { id: 1, name: "abc" },
    { id: 2, name: "xyz" },
    { id: 1, name: "abc" },
  ],
  (v) => v.id
);
// output
// [
//   { id: 1, name: "abc" },
//   { id: 2, name: "xyz" },
// ];

评论

0赞 Danish 5/31/2021
use 也可以使用 uniqBy 而不是 uniqueBy
2赞 user239558 2/21/2021 #66

这是一个几乎是单行的 O(n),保留了第一个元素,并且你可以将你正在使用的字段分开。

这是函数式编程中一种非常常见的技术 - 你用它来构建一个你返回的数组。由于我们像这样构建数组,因此我们保证了我们得到一个稳定的排序,这与这种方法不同。我们仍然使用 a 来确保我们没有重复项,因此我们的累加器同时包含 a 和我们正在构建的数组。reduce[...new Set(array)]SetSet

const removeDuplicates = (arr) =>
  arr.reduce(
    ([set, acc], item) => set.has(item) ? [set, acc] : [set.add(item), (acc.push(item), acc)],
    [new Set(), []]
  )[1]

以上方法适用于简单值,但不适用于对象,类似于分解方式。如果项是包含属性的对象,则执行以下操作:[...new Set(array)]id

const removeDuplicates = (arr) =>
  arr.reduce(
    ([set, acc], item) => set.has(item.id) ? [set, acc] : [set.add(item.id), (acc.push(item), acc)],
    [new Set(), []]
  )[1]

2赞 moshfiqrony 5/25/2021 #67

要删除重复项,可能有两种情况。 首先,所有数据都不是对象,其次,所有数据都是对象。

如果所有数据都是任何类型的原始数据类型,如 int、float、string 等,那么你可以遵循这个

const uniqueArray = [...new Set(oldArray)]

但是假设您的数组包含 JS 对象,如下所示

{
    id: 1,
    name: 'rony',
    email: '[email protected]'
}

然后要获取所有独特的对象,您可以按照以下操作

let uniqueIds = [];
const uniqueUsers = oldArray.filter(item => {
    if(uniqueIds.includes(item.id)){
        return false;
    }else{
        uniqueIds.push(item.id);
        return true;
    }
})

您还可以使用此方法使任何类型的数组都具有唯一性。只需将跟踪键保留在阵列上即可。uniqueIds

0赞 Ballpin 8/11/2021 #68

就我而言,这是最简单的解决方案

// A way to check if the arrays are equal
const a = ['A', 'B', 'C'].sort().toString()
const b = ['A', 'C', 'B'].sort().toString()

console.log(a === b); // true


// Test Case
const data = [
  { group: 'A', name: 'SD' },
  { group: 'B', name: 'FI' },
  { group: 'A', name: 'SD' },
  { group: 'B', name: 'CO' }
];

// Return a new Array without dublocates
function unique(data) {
  return data.reduce(function (accumulator, currentValue) {
    // Convert to string in order to check if they are the same value.
    const currentKeys = Object.keys(currentValue).sort().toString();
    const currentValues = Object.values(currentValue).sort().toString();

    let hasObject = false
    
    for (const obj of accumulator) {
      // Convert keys and values into strings so we can
      // see if they are equal with the currentValue
      const keys = Object.keys(obj).sort().toString();
      const values = Object.values(obj).sort().toString();
      // Check if keys and values are equal
      if (keys === currentKeys && values === currentValues) {
        hasObject = true
      }
    }

    // Push the object if it does not exist already.
    if (!hasObject) {
      accumulator.push(currentValue)
    }

    return accumulator
  }, []);
}

// Run Test Case
console.log(unique(data)); // [ { group: 'A', name: 'SD' }, { group: 'B', name: 'FI' }, { group: 'B', name: 'CO' } ]

-1赞 Ylama 8/17/2021 #69

使用 mongoose,我有一个 ObjectId 数组可供使用。

我有一个对象 ID 数组/列表要使用,首先需要将其设置为字符串,然后在唯一设置之后,修改回对象 ID。

var mongoose = require('mongoose')

var ids = [ObjectId("1"), ObjectId("2"), ObjectId("3")]

var toStringIds = ids.map(e => '' + e)
let uniqueIds = [...new Set(toStringIds)]
uniqueIds = uniqueIds.map(b => mongoose.Types.ObjectId(b))


console.log("uniqueIds :", uniqueIds)

-3赞 Artisan72 8/18/2021 #70

我会对数组进行排序,然后所有重复项都是邻居。 然后遍历阵列一次并消除所有重复项。

function getUniques(array) {
  var l = array.length
  if(l > 1) {
    // get a cloned copy and sort it
    array = [...array].sort();
    var i = 1, j = 0;
    while(i < l) {
      if(array[i] != array[j]) {
        array[++j] = array[i];
      }
      i++;
    }
    array.length = j + 1;
  }
  return array;
}
22赞 Blackjack 9/20/2021 #71

您可以同时使用内置函数和Array.prototype.filter()Array.prototype.indexOf()

array.filter((x, y) => array.indexOf(x) == y)

var arr = [1, 2, 3, 3, 4, 5, 5, 5, 6, 7, 8, 9, 6, 9];

var newarr = arr.filter((x, y) => arr.indexOf(x) == y);

console.log(newarr);

4赞 lonix 10/12/2021 #72

如前所述,如果您可以使用,这是最佳选择。[...new Set(values)]

否则,这里有一个单行代码,它不会为每个索引迭代数组:

values.sort().filter((val, index, arr) => index === 0 ? true : val !== arr[index - 1]);

它只是将每个值与之前的值进行比较。将对结果进行排序。

例:

let values = [ 1, 2, 3, 3, 4, 5, 5, 5, 4, 4, 4, 5, 1, 1, 1, 3, 3 ];
let unique = values.sort().filter((val, index, arr) => index === 0 ? true : val !== arr[index - 1]);
console.log(unique);

评论

0赞 Ponciusz 11/12/2021
当行中有多个相同的值时不起作用
0赞 lonix 11/13/2021
添加了代码片段,似乎有效。
2赞 Muhammad Atif Akram 11/2/2021 #73

  var myArray = ["a",2, "a", 2, "b", "1"];
  const uniques = [];
  myArray.forEach((t) => !uniques.includes(t) && uniques.push(t));
  console.log(uniques);

1赞 Re_p1ay 11/9/2021 #74

如果你想删除重复项,返回整个对象,并希望使用 ES6 Set 和 Map 语法,并且只运行一个循环,你可以试试这个,以获得唯一的 ID:

const collection = [{id:3, name: "A"}, {id:3, name: "B"}, {id:4, name: "C"}, {id:5, name: "D"}]

function returnUnique(itemsCollection){
  const itemsMap = new Map();

  itemsCollection.forEach(item => {
    if(itemsMap.size === 0){
      itemsMap.set(item.id, item)       
    }else if(!itemsMap.has(item.id)){
      itemsMap.set(item.id, item)
    }
  });
  
    return [...new Set(itemsMap.values())];
 }

console.log(returnUnique(collection));

0赞 Mike Reiche 11/14/2021 #75

这是另一种使用比较器的方法(我更关心干净的代码而不是性能):

const list = [
    {name: "Meier"},
    {name: "Hans"},
    {name: "Meier"},
]
const compare = (a, b) => a.name.localeCompare(b.name);
const uniqueNames = list.makeUnique(compare);
uniqueNames.pushIfAbsent({name: "Hans"}, compare);

原型声明:

declare global {
    interface Array<T>  {
        pushIfAbsent(item: T, compare:(a:T, b:T)=>number): number;
    }
    interface Array<T>  {
        makeUnique(compare:(a:T, b:T)=>number): Array<T>;
    }
}
Array.prototype.pushIfAbsent = function <T>(this:T[], item:T, compare:(a:T, b:T)=>number) {
    if (!this.find(existing => compare(existing, item)===0)) {
        return this.push(item)
    } else {
        return this.length;
    }
}
Array.prototype.makeUnique = function <T>(this:T[], compare:(a:T, b:T)=>number) {
    return this.filter((existing, index, self) => self.findIndex(item => compare(existing, item) == 0) == index);
}
0赞 vitaly-t 11/17/2021 #76

一种可扩展、快速、高效且易于阅读的现代方法,使用 iter-ops 库:

import {pipe, distinct} from 'iter-ops';

const input = [1, 1, 2, 2, 2, 3]; // our data

const i = pipe(input, distinct()); // distinct iterable

console.log([...i]); //=> [1, 2, 3]

如果你的输入是一个对象数组,你只需为运算符提供一个键选择器。distinct

2赞 rop 12/6/2021 #77

这并不是对原始问题的直接字面答案,因为我更喜欢从一开始就不要在数组中包含重复值。所以这是我的 UniqueArray

class UniqueArray extends Array {
    constructor(...args) {
        super(...new Set(args));
    }
    push(...args) {
        for (const a of args) if (!this.includes(a)) super.push(a);
        return this.length;
    }
    unshift(...args) {
        for (const a of args.reverse()) if (!this.includes(a)) super.unshift(a);
        return this.length;
    }
    concat(...args) {
        var r = new UniqueArray(...this);
        for (const a of args) r.push(...a);
        return r;
    }
}
> a = new UniqueArray(1,2,3,1,2,4,5,1)
UniqueArray(5) [ 1, 2, 3, 4, 5 ]
> a.push(1,4,6)
6
> a
UniqueArray(6) [ 1, 2, 3, 4, 5, 6 ]
> a.unshift(1)
6
> a
UniqueArray(6) [ 1, 2, 3, 4, 5, 6 ]
> a.unshift(0)
7
> a
UniqueArray(7) [
  0, 1, 2, 3,
  4, 5, 6
]
> a.concat(2,3,7)
UniqueArray(8) [
  0, 1, 2, 3,
  4, 5, 6, 7
]
3赞 Kalana Weerarathne 12/14/2021 #78

let ar = [1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 2, 1];
let unique = ar.filter((value, index) => {
        return ar.indexOf(value) == index;
      });
console.log(unique);

69赞 Surbhi Dighe 12/24/2021 #79

使用 ES6 new Set

var array = [3,7,5,3,2,5,2,7];
var unique_array = [...new Set(array)];
console.log(unique_array);    // output = [3,7,5,2]

使用 For 循环

var array = [3,7,5,3,2,5,2,7];

for(var i=0;i<array.length;i++) {
    for(var j=i+1;j<array.length;j++) {
        if(array[i]===array[j]) {
            array.splice(j,1);
        }
    }
}
console.log(array); // output = [3,7,5,2]

101赞 mdmundo 1/26/2022 #80

使用 Set 删除重复项。

Array有重复项

const withDuplicates = [2, 2, 5, 5, 1, 1, 2, 2, 3, 3];

使用 Set 获取没有重复项的新数组

const withoutDuplicates = Array.from(new Set(withDuplicates));

较短的版本

const withoutDuplicates = [...new Set(withDuplicates)];

结果:[2, 5, 1, 3]

评论

2赞 vsync 6/21/2022
对于在此之前几年给出的其他答案,完全重复。
0赞 Vivekraj K R 2/26/2022 #81

已经有很多很好的答案了。这是我的方法。

var removeDuplicates = function(nums) {
    let filteredArr = [];
    nums.forEach((item) => {
        if(!filteredArr.includes(item)) {
            filteredArr.push(item);
        }
    })

  return filteredArr;
}
1赞 rotarydial 3/9/2022 #82

对于元组数组,我会将内容放入 Map 中,让它完成工作。使用这种方法时,您必须注意要使用的密钥:

const arrayOfArraysWithDuplicates = [
    [1, 'AB'],
    [2, 'CD'],
    [3, 'EF'],
    [1, 'AB'],
    [2, 'CD'],
    [3, 'EF'],
    [3, 'GH'],
]

const uniqueByFirstValue = new Map();
const uniqueBySecondValue = new Map();

arrayOfArraysWithDuplicates.forEach((item) => {
    uniqueByFirstValue.set(item[0], item[1]);
    uniqueBySecondValue.set(item[1], item[0]);
});

let uniqueList = Array.from( uniqueByFirstValue, ( [ value, name ] ) => ( [value, name] ) );

console.log('Unique by first value:');
console.log(uniqueList);

uniqueList = Array.from( uniqueBySecondValue, ( [ value, name ] ) => ( [value, name] ) );

console.log('Unique by second value:');
console.log(uniqueList);

输出:

Unique by first value:
[ [ 1, 'AB' ], [ 2, 'CD' ], [ 3, 'GH' ] ]

Unique by second value:
[ [ 'AB', 1 ], [ 'CD', 2 ], [ 'EF', 3 ], [ 'GH', 3 ] ]
1赞 Yadab Sd 5/13/2022 #83

永远记住, 内置方法易于使用。但请记住,它们具有复杂性。

基本逻辑是最好的。没有隐藏的复杂性。

let list = [1, 1, 2, 100, 2] // your array
let check = {}
list = list.filter(item => {
    if(!check[item]) {
        check[item] = true
        return true;
    }
})

或者使用,let check = [] 如果你将来需要遍历检查的项目(虽然浪费内存)

评论

0赞 Aakash 5/14/2022
也许在提出这个问题时没有发布 filter()。
0赞 coder9833idls 5/28/2022
这会返回没有重复项的新数组吗?
0赞 Yadab Sd 5/29/2022
是的@coder9833idls
0赞 coder9833idls 5/28/2022 #84

ES2016 .includes() 一种方法简单答案:

var arr = [1,5,2,4,1,6]
function getOrigs(arr) {
  let unique = []
  arr && arr.forEach(number => {
    !unique.includes(number) && unique.push(number)
    if (number === arr[arr.length - 1]) {
      console.log('unique: ', unique)
    }
  })
}
getOrigs(arr)

请改用以下命令:

  • 更高 ES 版本
  • 简单的问题不应该使用多个高级 JS 方法,push()、length() 和 forEach() 很常见
  • 使用封盖,更易于阅读
  • 在内存、垃圾回收和性能方面似乎比其他的更好
  • 更少的代码行:如果根据行尾的位置分隔行,则只需要一行逻辑(因此您可以根据需要调用或重构此单行代码):
var arr = [1,5,2,4,1,6];
function getOrigs(arr) {let unique = []; 
  arr && arr.forEach(number => !unique.includes(number) && unique.push(number) && ((number === arr[arr.length - 1]) && console.log('unique: ', unique)))};
getOrigs(arr);
2赞 Seshu Vuggina 9/12/2022 #85

使用 ES6(单行)

基元值数组

let originalArr= ['a', 1, 'a', 2, '1'];

let uniqueArr = [...new Set(originalArr)];

对象数组

let uniqueObjArr = [...new Map(originalObjArr.map((item) => [item["propertyName"], item])).values()];

const ObjArray = [
    {
        name: "Eva Devore",
        character: "Evandra",
        episodes: 15,
    },
    {
        name: "Alessia Medina",
        character: "Nixie",
        episodes: 15,
    },
    {
        name: "Kendall Drury",
        character: "DM",
        episodes: 15,
    },
    {
        name: "Thomas Taufan",
        character: "Antrius",
        episodes: 14,
    },
    {
        name: "Alessia Medina",
        character: "Nixie",
        episodes: 15,
    },
];

let uniqueObjArray = [...new Map(ObjArray.map((item) => [item["id"], item])).values()];
3赞 Bishnu Das 9/16/2022 #86

您可以使用 Set 来消除重复项。

const originalNumbers = [1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 1, 2, 9];
const uniqueNumbersSet = new Set(originalNumbers);

/** get the array back from the set */
const uniqueNumbersArray = Array.from(uniqueNumbersSet);

/** uniqueNumbersArray outputs to: [1, 2, 3, 4, 5, 9] */

了解有关 set: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set 的更多信息

评论

0赞 Mayank Dudakiya 2/8/2023
JavaScript 确实是生成唯一数组的好方法Set()
8赞 MUHAMMAD USMAN 10/4/2022 #87

在 ES6/Later 中

仅获取唯一值

  let a = [
           { id: 1, name: "usman" },
           { id: 2, name: "zia" },
           { id: 3, name: "usman" },
          ];
const unique = [...new Set(a.map((item) => item.name))];
console.log(unique); // ["usman", "zia"]

获取唯一对象

const myObjArray = [
                       { id: 1, name: "usman" },
                       { id: 2, name: "zia" },
                       { id: 3, name: "usman" },
                   ];
// Creates an array of objects with unique "name" property values.
let uniqueObjArray = [
  ...new Map(myObjArray.map((item) => [item["name"], item])).values(),
];

console.log("uniqueObjArray", uniqueObjArray);
0赞 Diego Gabriel Corcuera 11/7/2022 #88

尝试这样做:

let d_array = [1, 2, 2, 3, 'a', 'b', 'b', 'c'];
d_array = d_array.filter((x,i)=>d_array.indexOf(x)===i);
console.log(d_array); // [1, 2, 3, "a", "b", "c"]

这将遍历数组,检查数组中同一条目的第一个搜索结果是否为当前索引,如果是,则允许它位于数组中。

3赞 Roohi Ali 11/13/2022 #89

一个简单的代码如下:

let arr = [1,'k',12,1,1,'k','12'];
let distictArr=arr.filter((item, index, arr) => arr.indexOf(item) === index);

console.log(distictArr); // [1, 'k', 12, '12']
0赞 shrekuu 12/2/2022 #90

我想从对象数组中删除重复项。重复项具有相同的 ID。这是我所做的。

// prev data
const prev = [
  {
    id: 1,
    name: "foo",
  },
  {
    id: 2,
    name: "baz",
  },
  {
    id: 1,
    name: "foo",
  },
];

// method:
// Step 1: put them in an object with the id as the key. Value of same id would get overriden.
// Step 2: get all the values.

const tempObj = {};
prev.forEach((n) => (tempObj[n.id] = n));
const next = Object.values(tempObj);

// result
[
  {
    id: 1,
    name: "foo",
  },
  {
    id: 2,
    name: "baz",
  }
];
0赞 Gino 4/18/2023 #91

简单

const listWithDupes = [1, 2, 3, 4, 5, 6, 7, 7, 8, 8, 8, 8, 8, 8, 9];

const uniqueList = Object.values(listWithDupes.reduce((acc, next) => ({ ...acc,
  [next]: next
}), {}));

console.log(uniqueList);

21赞 FreePhoenix888 7/3/2023 #92

基元值

套装(推荐)

var array = ["FreePhoenix888", "FreePhoenix888", "konard", "FreePhoenix888"];

let set = [...new Set(array)];

console.log(set); // ["FreePhoenix888", "konard"]

套装

function filterUniqueObjects(value, index, array) {
  return array.indexOf(value) === index;
}

// usage example:
var array = ["FreePhoenix888", "FreePhoenix888", "konard", "FreePhoenix888"];
var arrayOfUniqueItems = array.filter(filterUniqueObjects);

console.log(arrayOfUniqueItems); // ["FreePhoenix888", "konard"]

对象

此示例演示如何不仅筛选基元值数组,还筛选对象数组。我添加了注释,以便更容易理解您可以根据自己的要求在那里更改哪些内容。

let array = [
  { name: '@deep-foundation/core', version: '0.0.2' },
  { name: '@deep-foundation/capacitor-device', version: '10.0.1' },
  { name: '@deep-foundation/capacitor-device', version: '10.0.2' },
];

// Of course you can inline this function as filter argument uniqueArray.filter((item, index, self) => self.findIndex(innerItem => innerItem.name === item.name) === index);
function filterUniqueObjects(value, index, self) {
  return (
    self.findIndex(
      // Modify this function as you desire. You may want to calculate uniqueness depending only on specific fields, not all
      (obj) => obj.name === value.name
    ) === index
  );
};

let uniqueArray = array
  .reverse() // If you want latest duplicates to remain
  .filter(filterUniqueObjects)
  .reverse(); // To get back to original order after first reverse

console.log(uniqueArray)

-2赞 jgphilpott 9/8/2023 #93

简短而甜蜜的原型解决方案:

Array.prototype.unique = function() {
  return [...new Set(this)]
}
0赞 Jenson M John 11/9/2023 #94

一种带有 2 个循环的旧方式。

let a = ["Messi", 23, false, 11, 17, true, 23, "Messi", "Sachin", "2023", true, "Sachin"];

let b = [];
    for (let i in a) {
        let found = false;
        for (let j in b) {
            if (a[i] === b[j]) {
                found = true;
                break;
            }
        }
        if (found === false) {
            b.push(a[i]);
        }
    }

console.log(b); //['Messi', 23, false, 11, 17, true, 'Sachin', '2023']
0赞 XM01 - stands with Palestine 12/10/2023 #95

ES6/ES2015 及更高版本中,您可以使用 SetSpread 运算符实现简洁的单行代码,用于过滤数组中的重复项:

let uniqueItems = Array.from(new Set(items));

此解决方案通过使用 Array.from() 将 Set 显式转换回数组来保持清晰度。最终结果是一个仅包含唯一项的数组:

[4, 5, 6, 3, 2, 23, 1]