Simple & Pure JavaScript Array.unique method with 5 lines of code
It's often to have an array that contains duplicate values and you want to make them unique. For example, you might have ["a", 1, "a", 2, "1", 1]
and want to get ["a", 1, 2, "1"]
.
Utilizing many features in JavaScript like prototypes and anonymous functions, you can get that result with 5 lines of code:
Array.prototype.unique = function() {
return this.filter(function (value, index, self) {
return self.indexOf(value) === index;
});
}
Usage:
var arr = ['a', 1, 'a', 2, '1']
arr.unique(); // => ['a', 1, 2, '1']
This solution does NOT require any dependencies like jQuery or prototype.js, and it works for arrays with mixed types!
How does it work?
The native method
filter
will loop through the array and leave only those entries that pass (i.e gettrue
return value) the given callback anonymous function.The callback anonymous function returns
true
if the entry is the first occurrence, andfalse
elsewhere. It uses the nativeindexOf
method which finds the index of the first occurrence of an entry in an array.
Talking about filter
and indexOf
native methods, they were introduced in ECMA-262 standard 5th edition, which means they are not supported in old browsers (<IE9). There are workarounds for filter and indexOf to get the same method to work, but it will no longer be a 5-lines code.
Reference: This protip is based on this answer.
Written by Tamer Shlash
Related protips
3 Responses
This is very nice, just a footnote, this only works with flat arrays, for example calling .uniq on arr = [[1], [1], [1]] does not work. This will require a more sophisticated solution based on item type.
But keep in mind this is a O(n^2) solution.
This is a really nice and compact solution, however I found it didn't work with objects. I have a version that does take into account objects and mixed value arrays:
var j = {};
this.forEach(function (v) {
var typ = (typeof v === 'object') ? 'object' : 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];
});