提问人:Mottie 提问时间:12/25/2009 最后编辑:casperOneMottie 更新时间:11/9/2023 访问量:3284769
获取 JavaScript 数组中的所有唯一值(删除重复项)
Get all unique values in a JavaScript array (remove duplicates)
问:
我有一个数字数组,我需要确保这些数字是唯一的。我在互联网上找到了下面的代码片段,它运行良好,直到数组中有零。我在 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 中的错误值。0
this[i]
如果数组的值为 0 或任何其他虚假值,则为虚假值。
评论
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
}
评论
o
1
如果你使用的是 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();
评论
还可以使用下划线.js。
console.log(_.uniq([1, 2, 1, 3, 1, 4]));
<script src="http://underscorejs.org/underscore-min.js"></script>
这将返回:
[1, 2, 3, 4]
评论
array = [...new Set(array)]
_.uniqWith(arrayOfObjects, _.isEqual)
_.uniqWith([{a: 2}, {b: 3}, {a: 2}], _.isEqual)
[{a: 2}, {b: 3}]
uniq()
您还可以使用 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函数从数组中获取所有唯一元素?
评论
从那以后,我找到了一个使用jQuery的好方法
arr = $.grep(arr, function(v, k){
return $.inArray(v ,arr) === k;
});
注意:此代码是从 Paul Irish 的鸭子打孔帖子中提取的 - 我忘了注明:P
评论
这个原型并不完全正确,因为如果我有一个像这样的数组:它将返回并且是字符串并且是一个整数;他们是不同的。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"]
评论
$foo = 'bar'
$foo
var foo
在 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']
本机方法将遍历数组,只保留那些通过给定回调函数的条目。filter
onlyUnique
onlyUnique
检查给定值是否是第一个出现的值。否则,它必须是重复的,不会被复制。
此解决方案无需任何额外的库(如jQuery或prototype.js)即可工作。
它也适用于具有混合值类型的数组。
对于不支持本机方法的旧浏览器(<ie9),您可以在 MDN 文档中找到 filter 和 indexOf 的解决方法。filter
indexOf
如果要保留值的最后一次出现,只需替换为 。indexOf
lastIndexOf
在 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
...
评论
.filter((v,i,a)=>a.indexOf(v)==i)
let unique_values = [...new Set(random_array)];
developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/......
无需扩展 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等)。
评论
filter
如果有人使用 knockoutjs
ko.utils.arrayGetDistinctValues()
顺便说一句,已经查看了所有实用程序。ko.utils.array*
我不确定为什么加布里埃尔·西尔维拉(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
)
如果顺序不重要,那么我们可以进行哈希并获取键以创建唯一数组。
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 将具有唯一的数组元素。
看来我们已经失去了拉斐尔的答案,这个答案在几年内一直是公认的答案。如果您没有混合类型数组,这是(至少在 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;
}
您还可以使用 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"}]
基于其他答案,这是另一个变体,它采用可选标志来选择策略(保留第一个出现或保留最后):
无需扩展 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]
另一个答案,只是因为我为我的特定用例写了一个答案。无论如何,我碰巧正在对数组进行排序,鉴于我正在排序,我可以使用它来删除重复数据。
请注意,我的排序处理我的特定数据类型,您可能需要不同的排序,具体取决于您拥有的元素类型。
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]);
}
}
};
这里的许多答案可能对初学者没有用。如果对数组进行重复数据删除很困难,他们真的会了解原型链,甚至 jQuery 吗?
在现代浏览器中,一个干净而简单的解决方案是将数据存储在一个 Set 中,该 Set 被设计为唯一值的列表。
const cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford'];
const uniqueCars = Array.from(new Set(cars));
console.log(uniqueCars);
将 Set 转换回数组很有用,这样你就可以轻松访问数组所具有的所有很棒的方法(功能)。还有其他方法可以做同样的事情。但你可能根本不需要,因为 Sets 有很多有用的功能,比如 forEach。Array.from
Array.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)
只需将您喜欢的任何数组的名称传递给它即可。
评论
["volvo","lincoln"]
Map
cars
set
Array.prototype
最简单、最快的(在 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 浏览器中的上述方法更快。
评论
unique
getUnique
input_array.length < 200
[...new Set(input_array)]
input_array.reduce((c, v) => {if (!c.includes(v)) c.push(v); return c;}, [])
我在 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;
}
这是堆的另一种解决方案。
我最近需要使排序列表唯一,我使用过滤器来跟踪对象中的前一项,如下所示:
uniqueArray = sortedArray.filter(function(e) {
if(e==this.last)
return false;
this.last=e; return true;
},{last:null});
["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;
}, []);
评论
[].reduce((p, c) => (p.some((item) => c.id === item.id) ? p : p.concat(c)), [])
此脚本修改数组,过滤掉重复的值。它适用于数字和字符串。
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)
评论
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)); };
使用对象键制作唯一数组,我尝试过以下
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]
评论
看看这个。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
});
评论
接受选择器的版本应该非常快速和简洁:
function unique(xs, f) {
var seen = {};
return xs.filter(function(x) {
var fx = (f && f(x)) || x;
return !seen[fx] && (seen[fx] = 1);
});
}
ES6/ES2015 的更新答案:使用 Set 和 spread 运算符(感谢 le-m),单行解决方案为:
let uniqueItems = [...new Set(items)]
哪个返回
[4, 5, 6, 3, 2, 23, 1]
评论
Array.from(new Set([[1,2],[1,2],[1,2,3]]))
Set
s
let s = new Set([{Foo:"Bar"}, {Foo:"Bar"}]);
Set { { Foo: 'Bar' }, { Foo: 'Bar' } }
Set
let o = {Foo:"Bar"};
let s2 = new Set([o,o]);
Set { { Foo: 'Bar' } }
Array.from( new Set( items ) )
这个不纯,它会修改数组,但这是最快的。如果你的更快,那么请在评论中写下;)
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"]
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
评论
在简单方法中查找唯一的 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]
评论
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")
使用 ES5 语法
list = list.filter(function (x, i, a) {
return a.indexOf(x) == i;
});
浏览器兼容性:IE9+
我知道这已经被回答得死去活来......但。。。
没有人提到 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>
对于字符串数组:
function removeDuplicatesFromArray(arr) {
const unique = {};
arr.forEach((word) => {
unique[word] = 1; // it doesn't really matter what goes here
});
return Object.keys(unique);
}
评论
a
h
var h = {}; for (var k in a) { h[a[k]] = true;}; var unique = Object.keys(h);
(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...
如果你有一个对象数组,并且你想要一个函数,比如说,通过一个 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);
}, [])
}
我将所有答案拆分为 4 种可能的解决方案:
- 使用对象防止重复
{ }
- 使用帮助程序数组
[ ]
- 用
filter + indexOf
- 奖金!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 表格中不可用,因此我无法对其进行测试。
我希望看到使用 object 的代码会获胜,因为它使用哈希。因此,我很高兴测试显示了该算法在 Chrome 和 IE 中的最佳结果。感谢 @rab 的代码。{ }
更新 2020
启用了 Google Script ES6 引擎。现在我测试了最后一个代码,它比 object 方法出现得更快。Sets
评论
uniqueItems = [...new Set(items)]
uniqueItems = [...new Set(items)]
Object.values(j);
使用 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);
这是一个 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"}}]
奇怪的是,这以前没有被建议过。要通过数组中的对象键(如下)删除重复项,您可以执行如下操作:id
const uniqArray = array.filter((obj, idx, arr) => (
arr.findIndex((o) => o.id === obj.id) === idx
))
评论
filter()
findIndex()
new Set()
我们可以使用 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]
如果您对额外的依赖项感到满意,或者您的代码库中已经有一个库,则可以使用 LoDash(或下划线)从数组中删除重复项。
用法
如果代码库中还没有它,请使用 npm 安装它:
npm install lodash
然后按如下方式使用它:
import _ from 'lodash';
let idArray = _.uniq ([
1,
2,
3,
3,
3
]);
console.dir(idArray);
外:
[ 1, 2, 3 ]
评论
_.uniqWith(objectArray, _.isEqual)
您可以使用 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>
使用 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']
(这是最简单的方法)
我有一个使用 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]
我遇到了一个稍微不同的问题,我需要从数组中删除具有重复 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);
魔法
a.filter( e => !(t[e]=e in t) )
O(n) 性能 - 我们假设您的数组位于 和 中。解释在这里 (+Jeppe impr.)a
t={}
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) ))
评论
in
for
unique(['2', 2]) // ['2'];
unique([[1, 7], [1, '7'], ['1', 7], ['1', '7']]) // [1, 7]
上面的对象答案在我对对象的用例中似乎对我不起作用。
我修改如下:
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];
});
现在,这似乎适用于对象、数组、具有混合值的数组、布尔值等。
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);
筛选出未定义的值和 null 值,因为大多数时候您不需要它们。
const uniques = myArray.filter(e => e).filter((e, i, a) => a.indexOf(e) === i);
或
const uniques = [...new Set(myArray.filter(e => e))];
有时我需要从对象数组中获取唯一实例。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], [])
此解决方案应该非常快,并且在许多情况下都有效。
- 将索引数组项转换为对象键
使用 Object.keys 函数
var indexArray = ["hi","welcome","welcome",1,-9]; var keyArray = {}; indexArray.forEach(function(item){ keyArray[item]=null; }); var uniqueArray = Object.keys(keyArray);
我有一个简单的例子,我们可以从数组中删除对象,这些对象在对象中具有重复的 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);
现在使用集合,您可以删除重复项并将它们转换回数组。
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);
很多人已经提到使用...
[...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
重复数据删除通常需要给定类型的相等运算符。但是,使用函数会阻止我们有效地利用 a 来确定重复项,因为回退到 .如您所知,不适用于引用类型。所以如果被困住了,我们是善良的,对吧?eq
Set
Set
===
===
出路很简单,就是使用一个转换器函数,它允许我们将一个(引用)类型转换为我们可以使用 .例如,我们可以使用哈希函数或数据结构,如果它不包含任何函数。Set
JSON.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"}]
有了这些组合器,我们可以非常灵活地处理各种重复数据删除问题。这不是斋戒方法,而是最具表现力和最通用的方法。
[...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]
评论
这个问题已经得到了很多回答,但它并没有满足我的特殊需求。
很多答案是这样的:
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.findIndex
array.prototype.indexOf
a.filter((item, pos, self) => self.findIndex(v => v.name === item.name) === pos);
评论
indexOf
findIndex
你可以试试这个:
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;
}
如果您只想获取唯一元素并删除重复一次的元素,则可以这样做:
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));
你根本不需要 .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 */
}
最简单的方法是将值转换为字符串,以筛选嵌套对象值。
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'}]
对于具有一些唯一 id 的基于对象的数组,我有一个简单的解决方案,您可以通过它按线性复杂度进行排序
function getUniqueArr(arr){
const mapObj = {};
arr.forEach(a => {
mapObj[a.id] = a
})
return Object.values(mapObj);
}
任务是从由任意类型(原始和非原始)组成的数组中获取唯一的数组。
基于使用的方法并不新鲜。这里利用了 和 方法。优点是通用性(适用于任何类型的数组)、简短的 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' ] */
评论
在我的解决方案中,我在过滤之前对数据进行排序:
const uniqSortedArray = dataArray.sort().filter((v, idx, t) => idx==0 || v != t[idx-1]);
在查看了这里所有 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 () 之后的所有内容:filter
2
2
includes
i+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]
评论
使用 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" },
// ];
评论
这是一个几乎是单行的 O(n),保留了第一个元素,并且你可以将你正在使用的字段分开。
这是函数式编程中一种非常常见的技术 - 你用它来构建一个你返回的数组。由于我们像这样构建数组,因此我们保证了我们得到一个稳定的排序,这与这种方法不同。我们仍然使用 a 来确保我们没有重复项,因此我们的累加器同时包含 a 和我们正在构建的数组。reduce
[...new Set(array)]
Set
Set
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]
要删除重复项,可能有两种情况。 首先,所有数据都不是对象,其次,所有数据都是对象。
如果所有数据都是任何类型的原始数据类型,如 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
就我而言,这是最简单的解决方案
// 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' } ]
使用 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)
我会对数组进行排序,然后所有重复项都是邻居。 然后遍历阵列一次并消除所有重复项。
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;
}
您可以同时使用内置函数和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);
如前所述,如果您可以使用,这是最佳选择。[...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);
评论
var myArray = ["a",2, "a", 2, "b", "1"];
const uniques = [];
myArray.forEach((t) => !uniques.includes(t) && uniques.push(t));
console.log(uniques);
如果你想删除重复项,返回整个对象,并希望使用 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));
这是另一种使用比较器的方法(我更关心干净的代码而不是性能):
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);
}
一种可扩展、快速、高效且易于阅读的现代方法,使用 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
这并不是对原始问题的直接字面答案,因为我更喜欢从一开始就不要在数组中包含重复值。所以这是我的 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
]
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);
使用 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]
使用 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]
评论
已经有很多很好的答案了。这是我的方法。
var removeDuplicates = function(nums) {
let filteredArr = [];
nums.forEach((item) => {
if(!filteredArr.includes(item)) {
filteredArr.push(item);
}
})
return filteredArr;
}
对于元组数组,我会将内容放入 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 ] ]
永远记住, 内置方法易于使用。但请记住,它们具有复杂性。
基本逻辑是最好的。没有隐藏的复杂性。
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 = [] 如果你将来需要遍历检查的项目(虽然浪费内存)
评论
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);
使用 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()];
您可以使用 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 的更多信息
评论
Set()
在 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);
尝试这样做:
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"]
这将遍历数组,检查数组中同一条目的第一个搜索结果是否为当前索引,如果是,则允许它位于数组中。
一个简单的代码如下:
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']
我想从对象数组中删除重复项。重复项具有相同的 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",
}
];
简单
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);
基元值
带套装
(推荐)
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)
简短而甜蜜的原型解决方案:
Array.prototype.unique = function() {
return [...new Set(this)]
}
一种带有 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']
在 ES6/ES2015 及更高版本中,您可以使用 Set 和 Spread 运算符实现简洁的单行代码,用于过滤数组中的重复项:
let uniqueItems = Array.from(new Set(items));
此解决方案通过使用 Array.from() 将 Set 显式转换回数组来保持清晰度。最终结果是一个仅包含唯一项的数组:
[4, 5, 6, 3, 2, 23, 1]
上一个:如何将某些内容附加到数组中?
评论
o
object
a
array
i
index
e