本文翻译自:Remove duplicate values from JS array [duplicate]
I have a very simple JavaScript array that may or may not contain duplicates. 我有一个非常简单的JavaScript数组,其中可能包含重复项,也可能不包含重复项。
var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
I need to remove the duplicates and put the unique values in a new array. 我需要删除重复项,并将唯一值放入新数组中。
I could point to all the codes that I've tried but I think it's useless because they don't work. 我可以指出我尝试过的所有代码,但是我认为这没用,因为它们不起作用。 I accept jQuery solutions too. 我也接受jQuery解决方案。
Similar question: 类似的问题:
- Get all non-unique values (ie: duplicate/more than one occurrence) in an array 获取数组中的所有非唯一值(即:重复/多次出现)
#1楼
参考:https://stackoom.com/question/cj3F/从JS数组中删除重复的值-duplicate
#2楼
Use Underscore.js 使用Underscore.js
It's a library with a host of functions for manipulating arrays. 这是一个包含用于操纵数组的函数的库。
It's the tie to go along with jQuery's tux, and Backbone.js's suspenders. 这是与jQuery的晚礼服和Backbone.js的吊带一起使用的纽带。
_.uniq(array, [isSorted], [iterator])
Alias: unique_.uniq(array, [isSorted], [iterator])
别名: 唯一
Produces a duplicate-free version of the array , using === to test object equality. 产生数组的无重复版本,使用===来测试对象的相等性。 If you know in advance that the array is sorted, passing true for isSorted will run a much faster algorithm. 如果您事先知道数组已排序,则为isSorted传递true将运行更快的算法。 If you want to compute unique items based on a transformation, pass an iterator function. 如果要基于转换计算唯一项,请传递迭代器函数。
var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
alert(_.uniq(names, false));
Note: Lo-Dash (an underscore competitor) also offers a comparable .uniq implementation. 注意: Lo-Dash ( 下划线竞争对手)还提供了类似的.uniq实现。
#3楼
The following is more than 80% faster than the jQuery method listed (see tests below). 以下内容比列出的jQuery方法快80%以上(请参见下面的测试)。 It is an answer from a similar question a few years ago. 这是几年前类似问题的答案。 If I come across the person who originally proposed it I will post credit. 如果我遇到最初提出该建议的人,我将记入贷方。 Pure JS. 纯JS。
var temp = {};
for (var i = 0; i < array.length; i++)
temp[array[i]] = true;
var r = [];
for (var k in temp)
r.push(k);
return r;
My test case comparison: http://jsperf.com/remove-duplicate-array-tests 我的测试用例比较: http : //jsperf.com/remove-duplicate-array-tests
#4楼
The top answers have complexity of O(n²)
, but this can be done with just O(n)
by using an object as a hash: 最高答案的复杂度为O(n²)
,但这可以通过将对象用作哈希来仅用O(n)
来完成:
function getDistinctArray(arr) {
var dups = {};
return arr.filter(function(el) {
var hash = el.valueOf();
var isDup = dups[hash];
dups[hash] = true;
return !isDup;
});
}
This will work for strings, numbers, and dates. 这将适用于字符串,数字和日期。 If your array contains objects, the above solution won't work because when coerced to a string, they will all have a value of "[object Object]"
(or something similar) and that isn't suitable as a lookup value. 如果您的数组包含对象,则上述解决方案将不起作用,因为当将其强制转换为字符串时,它们都将具有"[object Object]"
(或类似名称)的值,并且不适合作为查找值。 You can get an O(n)
implementation for objects by setting a flag on the object itself: 您可以通过在对象本身上设置标志来获得对象的O(n)
实现:
function getDistinctObjArray(arr) {
var distinctArr = arr.filter(function(el) {
var isDup = el.inArray;
el.inArray = true;
return !isDup;
});
distinctArr.forEach(function(el) {
delete el.inArray;
});
return distinctArr;
}
2019 edit: Modern versions of JavaScript make this a much easier problem to solve. 2019编辑:现代版本的JavaScript使这个问题更容易解决。 Using Set
will work, regardless of whether your array contains objects, strings, numbers, or any other type. 无论您的数组包含对象,字符串,数字还是任何其他类型,都可以使用Set
进行工作。
function getDistinctArray(arr) {
return [...new Set(arr)];
}
The implementation is so simple, defining a function is no longer warranted. 实现是如此简单,不再需要定义功能。
#5楼
A single line version using array filter and indexOf functions: 使用数组过滤器和indexOf函数的单行版本:
arr = arr.filter (function (value, index, array) {
return array.indexOf (value) == index;
});
#6楼
Got tired of seeing all bad examples with for-loops or jQuery. 厌倦了使用for循环或jQuery查看所有不良示例。 Javascript has the perfect tools for this nowadays: sort, map and reduce. 如今,JavaScript具有完美的工具:排序,映射和归约。
Uniq reduce while keeping existing order 在保持现有订单的同时减少Uniq
var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
var uniq = names.reduce(function(a,b){
if (a.indexOf(b) < 0 ) a.push(b);
return a;
},[]);
console.log(uniq, names) // [ 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl' ]
// one liner
return names.reduce(function(a,b){if(a.indexOf(b)<0)a.push(b);return a;},[]);
Faster uniq with sorting 排序更快的uniq
There are probably faster ways but this one is pretty decent. 可能有更快的方法,但是这一方法相当不错。
var uniq = names.slice() // slice makes copy of array before sorting it
.sort(function(a,b){
return a > b;
})
.reduce(function(a,b){
if (a.slice(-1)[0] !== b) a.push(b); // slice(-1)[0] means last item in array without removing it (like .pop())
return a;
},[]); // this empty array becomes the starting value for a
// one liner
return names.slice().sort(function(a,b){return a > b}).reduce(function(a,b){if (a.slice(-1)[0] !== b) a.push(b);return a;},[]);
Update 2015: ES6 version: 2015年更新:ES6版本:
In ES6 you have Sets and Spread which makes it very easy and performant to remove all duplicates: 在ES6中,您可以使用Sets and Spread来轻松且高效地删除所有重复项:
var uniq = [ ...new Set(names) ]; // [ 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl' ]
Sort based on occurrence: 根据出现次数排序:
Someone asked about ordering the results based on how many unique names there are: 有人问根据有多少个唯一名称对结果进行排序:
var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']
var uniq = names
.map((name) => {
return {count: 1, name: name}
})
.reduce((a, b) => {
a[b.name] = (a[b.name] || 0) + b.count
return a
}, {})
var sorted = Object.keys(uniq).sort((a, b) => uniq[a] < uniq[b])
console.log(sorted)