I know this is a basic trick but many times useful in IE too:
Array.prototype.indexOf=function(o,i){for(var j=this.length,i=i<0?i+j<0?0:i+j:i||0;i<j&&this[i]!==o;i++);return j<=i?-1:i}
That's all ... in the most compact way ... but what about most compact lastIndexOf prototype?
Array.prototype.lastIndexOf=function(o,i){var s=this,r=s.reverse().indexOf(o,i);s.reverse();return r}
Update
Thanks to Laurent, the most compact lastIndexOf should be this one:
Array.prototype.lastIndexOf=function(o,i){return this.slice(0).reverse().indexOf(o,i)}
Probably one slice instead of two reverse should be a better choice? I'll test them :-)
Performances? Good enough ... Compatibility? IE4 or greater!
These are shorter and imho a little cleaner.
ReplyDeleteindexOf:
function(a){return this.reverse().lastIndexOf(a);}
lastIndexOf:
function(a){for(var i=this.length-1; i>-1 && a!==this[i]; --i); return i;}
These are wrong, because not standard and indexOf will reverse every Array.
ReplyDeletevar a = [1,2,3];
a.reverse();
alert(a); // [3,2,1]
reverse return an array but reverse internal indexes too ... since JavaScript 1.0.
Regards
Ah right, so a quick fix for indexOf would go something like:
ReplyDeleteindexOf:
function(a){var i=this.reverse().lastIndexOf(a); this.reverse(); return i;}
I don't see how the reverse internal indices affect the js however, since I'm using an external counter, so to speak.
Actually it would be better to do something like this for indexOf:
ReplyDeletefunction(a){return this.slice(0).reverse().lastIndexOf(a);}
Laurent, your last proposal seems interesting but it's not standard.
ReplyDeletePlease read correct indexOf and lastIndexOf implementation:
JavaScript MDC
At the same time, slice create a copy and I don't know how much this should increase memory or CPU usage.
You can also remove 1 byte by rewriting the return statement in the indexOf function as follows:
ReplyDeletereturn i<j?i:-1
Sorry this is late, but I only just saw this.
ReplyDeleteYou can save a couple more characters by making 'j' a parameter instead of using 'var':
function(o,i,j){for(j=...
And I think you can use the binary operator '&' instead of '&&'. Not sure if that's portable though.
It will also sometimes do an out of bounds array access, and an extra comparison but I think it's still correct.
You can save a couple more characters by making 'j' a parameter instead of using 'var'
ReplyDeleteThat's not standard ... and a dynamic language need to do more check each time You call function (was third parameter sent? what' its real value?)
& intead of && is not the same ... so, again, You found here the shortest Array.prototype.indexOf :-)
function dbjIndexOf( elem, array )
ReplyDelete{
var i = array.length ;
do {
if ( i-- === 0 ) return i ;
} while ( array[i] !== elem ) ;
return i ;
}
DBJ your indexOf does NOT respect SPECs
ReplyDeleteif you don't need to follow specs, this is the shortest:
ReplyDeletefunction indexOf(v){
for(var i=this.length;i--&&this[i]!==v;);
return i
};