-
-
Save jed/1044540 to your computer and use it in GitHub Desktop.
// from http://twitter.com/WebReflection/status/83867362490720258 | |
Array.prototype.unique = // extend the array prototype | |
[].unique || // if it doesn't exist | |
function( | |
a | |
){ | |
return function() { // with a function that | |
return this.filter(a) // filters by the cached function | |
} | |
}( | |
function(a,b,c) { // which | |
return c.indexOf( // finds out whether the array contains | |
a, // the item | |
b + 1 // after the current index | |
) < 0 // and returns false if it does. | |
} | |
) |
Array.prototype.unique=function(a){return function(){return this.filter(a)}}(function(a,b,c){return c.indexOf(a,b+1)<0}) |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
Version 2, December 2004 | |
Copyright (C) 2011 Jed Schmidt <http://jed.is> | |
Everyone is permitted to copy and distribute verbatim or modified | |
copies of this license document, and changing it is allowed as long | |
as the name is changed. | |
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
0. You just DO WHAT THE FUCK YOU WANT TO. |
{ | |
"name": "unique", | |
"description": "Array.prototype.unique, by @WebReflection", | |
"keywords": [ | |
"array", | |
"unique" | |
] | |
} |
<!DOCTYPE html> | |
<title>Foo</title> | |
<div>Expected value: <b>1,2,3,4,5</b></div> | |
<div>Actual value: <b id="ret"></b></div> | |
<script> | |
Array.prototype.unique=function(a){return function(){return this.filter(a)}}(function(a,b,c){return c.indexOf(a,b+1)<0}) | |
document.getElementById( "ret" ).innerHTML = [1,2,3,4,5,4,3,2,1].unique().sort() | |
</script> |
try it and you'll see why. ;)
Got it. Well, then how about
Array.prototype.unique=[].unique||function(a,b){for(a=this,b=a.length;b--;a.indexOf(a[b])<b&&a.splice(b,1));return a}
does not forcefully overwrite the original method and is still 3 bytes shorter.
it may be shorter, but it's also destructive. probably not a good idea for something like unique
.
A bit longer (133 chars), but not destructive:
Array.prototype.unique||(Array.prototype.unique=function(a,b){for(a=this,b=a.length;b--;a.indexOf(a[b])<b&&a.splice(b,1));return a})
Or if you want to use your filter version (even shorter), take one of the anonymous functions out of the closure:
Array.prototype.unique||(Array.prototype.unique=function(){return this.filter(function(a,b,c){return c.indexOf(a,b+1)<0})})
this isn't an ES5 shim, so i'm not sure we need to worry about overwriting anything. by destructive i mean that your version mutates the original array.
Ah, well, then at least the removal of the closure should bring some less bytes.
well, given it's a bit of an expensive operation, i'd prefer the caching of the function. @WebReflection has a really good sense for that stuff.
hi. awesome function, thanks on that!
on a = [ 1,2,3,4,3,2,1] your version returns
[4, 3, 2, 1]
which might be disappointing if we want to have the first occurrence to be first in result set
so if you do it like that
Array.prototype.unique=function(a){return function(){return this.filter(a)}}(function(a,b,c){return c.indexOf(a)==b})
it'll return
[1, 2, 3, 4]
of course it might affect performance
thanks again!
[1,2,3,1].reduce((acc, item) => acc.includes(item) ? acc : acc.concat(item), [])
is simpler
Array.prototype.uniq =
Array.prototype.unique =
( () => function()
{ return [ ...new Set( this ) ] }
) ()
What about using ~ instead of <0?