Una esperanza bidireccional indexOf
/ lastIndexOf
alternativa más rápida
2015
Si bien el nuevo método incluye es muy bueno, el soporte es básicamente cero por ahora.
Hace mucho tiempo que estaba pensando en la forma de reemplazar las funciones slow indexOf / lastIndexOf.
Ya se ha encontrado una forma eficaz, mirando las respuestas principales. De esos elegí la contains
función publicada por @Damir Zekic, que debería ser la más rápida. Pero también establece que los puntos de referencia son de 2008 y, por lo tanto, están desactualizados.
También prefiero while
sobre for
, pero por una razón no específica terminé escribiendo la función con un bucle for. También se podría hacer con un while --
.
Tenía curiosidad si la iteración era mucho más lenta si revisaba ambos lados de la matriz mientras lo hacía. Aparentemente no, por lo que esta función es aproximadamente dos veces más rápida que las más votadas. Obviamente también es más rápido que el nativo. Esto en un entorno del mundo real, donde nunca se sabe si el valor que está buscando está al principio o al final de la matriz.
Cuando sabe que acaba de insertar una matriz con un valor, usar lastIndexOf sigue siendo probablemente la mejor solución, pero si tiene que viajar a través de grandes matrices y el resultado podría estar en todas partes, esta podría ser una solución sólida para acelerar las cosas.
Bidirectional indexOf / lastIndexOf
function bidirectionalIndexOf(a, b, c, d, e){
for(c=a.length,d=c*1; c--; ){
if(a[c]==b) return c; //or this[c]===b
if(a[e=d-1-c]==b) return e; //or a[e=d-1-c]===b
}
return -1
}
//Usage
bidirectionalIndexOf(array,'value');
Prueba de rendimiento
http://jsperf.com/bidirectionalindexof
Como prueba, creé una matriz con 100k entradas.
Tres consultas: al principio, en el medio y al final de la matriz.
Espero que también encuentres esto interesante y pruebes el rendimiento.
Nota: Como puede ver, modifiqué ligeramente la contains
función para reflejar la salida indexOf & lastIndexOf (básicamente, true
con index
y false
con -1
). Eso no debería dañarlo.
La variante prototipo de matriz
Object.defineProperty(Array.prototype,'bidirectionalIndexOf',{value:function(b,c,d,e){
for(c=this.length,d=c*1; c--; ){
if(this[c]==b) return c; //or this[c]===b
if(this[e=d-1-c] == b) return e; //or this[e=d-1-c]===b
}
return -1
},writable:false, enumerable:false});
// Usage
array.bidirectionalIndexOf('value');
La función también se puede modificar fácilmente para devolver verdadero o falso o incluso el objeto, cadena o lo que sea.
Y aquí está la while
variante:
function bidirectionalIndexOf(a, b, c, d){
c=a.length; d=c-1;
while(c--){
if(b===a[c]) return c;
if(b===a[d-c]) return d-c;
}
return c
}
// Usage
bidirectionalIndexOf(array,'value');
¿Cómo es esto posible?
Creo que el cálculo simple para obtener el índice reflejado en una matriz es tan simple que es dos veces más rápido que hacer una iteración de bucle real.
Aquí hay un ejemplo complejo que realiza tres comprobaciones por iteración, pero esto solo es posible con un cálculo más largo que causa la desaceleración del código.
http://jsperf.com/bidirectionalindexof/2