I have an array of numbers that I need to make sure are unique. I found the code snippet below on the internet and it works great until the array has a zero in it. I found this other script here on SO that looks almost exactly like it, but it doesn't fail.
So for the sake of helping me learn, can someone help me determine where the prototype script is going wrong?
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;
}
The simplest, and fastest (in Chrome) way of doing this:
Simply goes through every item in the array, tests if that item is already in the list, and if it's not, push to the array that gets returned.
According to jsPerf, this function is the fastest of the ones I could find anywhere - feel free to add your own though.
The non-prototype version:
Sorting
When also needing to sort the array, the following is the fastest:
or non-prototype:
This is also faster than the above method in most non-chrome browsers.
You can also use sugar.js:
Shortest solution with ES6:
[...new Set( [1, 1, 2] )];
Or if you want to modify the Array prototype (like in the original question):
EcmaScript 6 is only partially implemented in modern browsers at the moment (Aug. 2015), but Babel has become very popular for transpiling ES6 (and even ES7) back to ES5. That way you can write ES6 code today!
If you're wondering what the
...
means, it's called the spread operator. From MDN: «The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected». Because a Set is an iterable (and can only have unique values), the spread operator will expand the Set to fill the array.Resources for learning ES6:
I found that serializing they hash key helped me get this working for objects.
One Liner, Pure JavaScript
With ES6 syntax
list = list.filter((x, i, a) => a.indexOf(x) == i)
With ES5 syntax
Browser Compatibility: IE9+