Skip to content

Instantly share code, notes, and snippets.

@bergus
Forked from lsauer/gist:1305056
Created November 23, 2011 04:01
Show Gist options
  • Save bergus/1387854 to your computer and use it in GitHub Desktop.
Save bergus/1387854 to your computer and use it in GitHub Desktop.
Correct easiest way to find duplicate values in a JavaScript array - Native unique function implementation
/*
* I saw this thread: http://stackoverflow.com/questions/840781/easiest-way-to-find-duplicate-values-in-a-javascript-array
* The solutions from gist:1305056 were elegant, but wrong. So here's mine:
*/
Array.prototype.unique = function(test) {
/* returns a new, sorted Array without duplicates */
if (!Array.isArray(this))
throw new TypeError("Array.prototype.unique must be called on an Array");
return this.slice(0).sort().filter( typeof test == "function"
? function(v, i, a) { return !i || !test(v, a[i-1]); }
: function(v, i, a) { return !i || v !== a[i-1]; }
);
};
// Short Snippet without type test:
Array.prototype.unique=function(test){return this.slice(0).sort().filter(typeof test=="function"?function(v, i, a){return !i||!test(v,a[i-1]);}:function(v,i,a){return !i||v!==a[i-1];});};
/*
* Numbers
*/
var arr = [324,3,32,0,5,52,2100,1,20,2,3,3,2,0,2,2,1,1,1];
//1. sorting / map
var a = arr.sort();
>>>[0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 20, 2100, 3, 3, 3, 32, 324, 5, 52]
//2. reduce
a.filter( function(v, i, a) { return !i || v !== a[i-1]; } );
[0, 1, 2, 20, 2100, 3, 32, 324, 5, 52]
/*
* Strings
*/
var a = 'Magic belongs to Jerry Harry Jerry Harry Potter and Banana Joe'.split(' ');
a = a.sort()
>>>["Banana", "Harry", "Harry", "Jerry", "Jerry", "Joe", "Magic", "Potter", "and", "belongs", "to"]
a.filter( function(v, i, a) { return !i || v !== a[i-1]; } );
>>>["Banana", "Harry", "Jerry", "Joe", "Magic", "Potter", "and", "belongs", "to"]
/**
* Additional information:
*
* you can also use a function to compare 2 items, which returns whether they are equal or not
* But watch out: items which are equal also must get sorted in the same way (after each other):
*/
[{id:1},{id:0},{id:2},{id:0}].sort();
>>>[{id:1},{id:0},{id:2},{id:0}] //they're sorted as "[Object object]" - equal
function Item(number){
this.id = number;
this.toString = function(){return this.id};
}
[new Item(1), new Item(0), new Item(2), new Item(0)].sort();
>>>[<0>, <0>, <1>, <2>]
[new Item(1), new Item(0), new Item(2), new Item(0)].unique(function(a, b){return a.id==b.id;});
>>>[<0>, <1>, <2>] // tadaa!
@mflodin
Copy link

mflodin commented Jan 10, 2012

Your results in the examples are missing an element. For instance "Banana" is missing from the filtered string array and 1 is missing from the filtered number array. The actual resulting arrays when running the code does include these elements.

@bergus
Copy link
Author

bergus commented Jan 10, 2012

@mflodin: Thanks for the pointer! However, not the code was wrong, but the example.

@mflodin
Copy link

mflodin commented Jan 10, 2012 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment