Created
August 12, 2011 09:01
-
-
Save uhop/1141741 to your computer and use it in GitHub Desktop.
dojo/array.js: indexOf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// dojo/array.js: forEach | |
/* | |
LEGEND: | |
old --- the previous implementation from Dojo trunk. | |
nnn --- the new implementation. | |
ech --- https://github.com/kriszyp/each | |
NOTES: | |
All functions are copied below together with all necessary utility functions. | |
*/ | |
var indexOf = index(true); | |
var a = noise(1); | |
this.group( | |
"1", | |
function old(){ dojo_indexOf(a, a[a.length - 1]); }, | |
function nnn(){ indexOf(a, a[a.length - 1]); }, | |
function ech(){ each(a, a[a.length - 1]); } | |
); | |
var b = noise(10); | |
this.group( | |
"10", | |
function old(){ dojo_indexOf(b, b[b.length - 1]); }, | |
function nnn(){ indexOf(b, b[b.length - 1]); }, | |
function ech(){ each(b, b[b.length - 1]); } | |
); | |
var c = noise(100); | |
this.group( | |
"100", | |
function old(){ dojo_indexOf(c, c[c.length - 1]); }, | |
function nnn(){ indexOf(c, c[c.length - 1]); }, | |
function ech(){ each(c, c[c.length - 1]); } | |
); | |
var d = noise(1000); | |
this.group( | |
"1000", | |
function old(){ dojo_indexOf(d, d[d.length - 1]); }, | |
function nnn(){ indexOf(d, d[d.length - 1]); }, | |
function ech(){ each(d, d[d.length - 1]); } | |
); | |
function noise(count){ | |
var a = new Array(count); | |
for(var i = 0; i < count; ++i){ | |
a[i] = Math.random(); | |
} | |
return a; | |
} | |
// old | |
function dojo_indexOf(/*Array*/arr, /*Object*/value, /*Integer?*/fromIndex, /*Boolean?*/findLast){ | |
if(!arr || !arr.length){ return -1; } | |
if(findLast){ | |
//return array.lastIndexOf(arr, value, fromIndex); | |
} | |
var end = arr.length, i = 0, u; | |
if(fromIndex === u){ fromIndex = i; } | |
if(fromIndex >= 0){ | |
i = fromIndex; | |
}else{ | |
i = end + fromIndex; | |
i = i > 0 ? i : 0; | |
} | |
for(;i<end; i++){ | |
if(arr[i] == value){ | |
return i; | |
} | |
} | |
return -1; | |
} | |
// new | |
var u; | |
function index(up){ | |
var delta = 1, lOver = 0, uOver = 0; | |
if(!up){ | |
delta = lOver = uOver = -1; | |
} | |
return function(a, x, from, last){ | |
if(last && delta > 0){ | |
// TODO: why do we use a non-standard signature? why do we need "last"? | |
//return array.lastIndexOf(a, x, from); | |
} | |
var l = a && a.length || 0, end = up ? l + uOver : lOver, i; | |
if(from === u){ | |
i = up ? lOver : l + uOver; | |
}else{ | |
if(from < 0){ | |
i = l + from; | |
if(i < 0){ | |
i = lOver; | |
} | |
}else{ | |
i = from >= l ? l + uOver : from; | |
} | |
} | |
if(l && typeof a == "string") a = a.split(""); | |
for(; i != end; i += delta){ | |
if(a[i] == x){ | |
return i; // Number | |
} | |
} | |
return -1; // Number | |
} | |
} | |
// each | |
function getEmit(result){ | |
return function(newValue){ | |
// emit function adds result to return array | |
result.push(newValue); | |
}; | |
} | |
function each(array, callback, thisObject){ | |
// create an emit function if there is enough arguments, otherwise avoid the allocation cost | |
var i = 0, result, emit, length = array.length; | |
if(typeof callback == "function"){ | |
// standard each usage, calling a callback on each item | |
if(callback.length > 2){ | |
emit = getEmit(result = []); | |
} | |
if(length > -1){ | |
if(thisObject){ | |
// iterate over array | |
for(;i < length; i++){ | |
// call the callback | |
var newValue = callback.call(thisObject, array[i], i, emit); | |
// if a value was returned, examine it | |
if(newValue !== undefined){ | |
// defined value breaks out of loop | |
return newValue; | |
} | |
} | |
}else{ | |
// we do a separate branch for when thisObject isn't provided because | |
// it is faster to avoid the .call() | |
for(;i < length; i++){ | |
// call the callback | |
var newValue = callback(array[i], i, emit); | |
// if a value was returned, examine it | |
if(newValue !== undefined){ | |
// defined value breaks out of loop | |
return newValue; | |
} | |
} | |
} | |
}else{ | |
// not an array, iterate over an object | |
for(i in array){ | |
if(array.hasOwnProperty(i)){ | |
var newValue = callback.call(thisObject, array[i], i, emit); | |
} | |
if(newValue !== undefined){ | |
// defined value breaks out of loop | |
return newValue; | |
} | |
} | |
} | |
return result; | |
} | |
// indexOf operation | |
for(i = thisObject || 0; i < length; i++){ | |
if(array[i] === callback){ | |
return i; | |
} | |
} | |
return -1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Benchmark it with http://www.perfjs.com/