Uma alternativa bidirecional indexOf
/ esperançosamente mais rápidalastIndexOf
2015
Embora o novo método inclua é muito bom, o suporte é basicamente zero por enquanto.
Há muito tempo que eu estava pensando em uma maneira de substituir as funções indexOf / lastIndexOf lentas.
Uma maneira de desempenho já foi encontrada, observando as principais respostas. Daqueles eu escolhi ocontains
função postada por @Damir Zekic, que deve ser a mais rápida. Mas também afirma que os benchmarks são de 2008 e estão desatualizados.
Eu também prefiro while
mais for
, mas por não um motivo específico Acabei escrevendo a função com um loop for. Também poderia ser feito com umwhile --
.
Fiquei curioso se a iteração era muito mais lenta se eu verificasse os dois lados da matriz enquanto fazia isso. Aparentemente não, e, portanto, essa função é cerca de duas vezes mais rápida do que as votadas com maior número de votos. Obviamente, também é mais rápido que o nativo. Isso em um ambiente do mundo real, onde você nunca sabe se o valor que está pesquisando está no início ou no final da matriz.
Quando você sabe que acabou de empurrar uma matriz com um valor, usar lastIndexOf provavelmente é a melhor solução, mas se você precisar percorrer grandes matrizes e o resultado puder estar em qualquer lugar, essa poderá ser uma solução sólida para tornar as coisas mais rápidas.
Índice bidirecionalOf / 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');
Teste de performance
http://jsperf.com/bidirectionalindexof
Como teste, criei uma matriz com 100 mil entradas.
Três consultas: no início, no meio e no final da matriz.
Espero que você também ache isso interessante e teste o desempenho.
Nota: Como você pode ver, modifiquei levemente a contains
função para refletir a saída indexOf & lastIndexOf (basicamente true
com os botões com index
e false
com -1
). Isso não deve prejudicá-lo.
A variante do protótipo 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');
A função também pode ser facilmente modificada para retornar verdadeiro ou falso, ou mesmo o objeto, a string ou o que for.
E aqui está a 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');
Como isso é possível?
Eu acho que o cálculo simples para obter o índice refletido em uma matriz é tão simples que é duas vezes mais rápido que fazer uma iteração de loop real.
Aqui está um exemplo complexo que faz três verificações por iteração, mas isso só é possível com um cálculo mais longo que causa a lentidão do código.
http://jsperf.com/bidirectionalindexof/2