Une solution bidirectionnelle indexOf
/ lastIndexOf
alternative, je l'espère, plus rapide
2015
Bien que la nouvelle méthode inclut soit très agréable, le support est pratiquement nul pour l'instant.
Cela fait longtemps que je pensais à un moyen de remplacer les fonctions slow indexOf / lastIndexOf.
Un moyen performant a déjà été trouvé, en regardant les meilleures réponses. Parmi ceux que j'ai choisiscontains
Parmi fonction publiée par @Damir Zekic qui devrait être la plus rapide. Mais il indique également que les repères datent de 2008 et sont donc dépassés.
Je préfère également while
plus for
, mais pour une raison non spécifique, j'ai fini d'écrire la fonction avec une boucle for. Cela pourrait aussi être fait avec unwhile --
.
J'étais curieux de savoir si l'itération était beaucoup plus lente si je vérifiais les deux côtés du tableau en le faisant. Apparemment non, et donc cette fonction est environ deux fois plus rapide que les meilleures votées. Évidemment, il est également plus rapide que le natif. Ceci dans un environnement réel, où vous ne savez jamais si la valeur que vous recherchez est au début ou à la fin du tableau.
Lorsque vous savez que vous venez de pousser un tableau avec une valeur, l'utilisation de lastIndexOf reste probablement la meilleure solution, mais si vous devez parcourir de grands tableaux et que le résultat pourrait être partout, cela pourrait être une solution solide pour accélérer les choses.
IndexOf / lastIndexOf bidirectionnel
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');
Test de performance
http://jsperf.com/bidirectionalindexof
Comme test, j'ai créé un tableau avec 100 000 entrées.
Trois requêtes: au début, au milieu et à la fin du tableau.
J'espère que vous trouverez également cela intéressant et testez les performances.
Remarque: Comme vous pouvez le voir, j'ai légèrement modifié la contains
fonction pour refléter la sortie indexOf & lastIndexOf (donc en gros true
avec index
et false
avec -1
). Cela ne devrait pas lui nuire.
La variante du prototype de matrice
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 fonction peut également être facilement modifiée pour retourner vrai ou faux ou même l'objet, la chaîne ou quoi que ce soit.
Et voici 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');
Comment est-ce possible?
Je pense que le calcul simple pour obtenir l'index réfléchi dans un tableau est si simple qu'il est deux fois plus rapide que de faire une itération de boucle réelle.
Voici un exemple complexe faisant trois vérifications par itération, mais cela n'est possible qu'avec un calcul plus long qui provoque le ralentissement du code.
http://jsperf.com/bidirectionalindexof/2