うまくいけば、より高速な双方向indexOf
/ lastIndexOf
代替
2015年
新しい方法にはは非常に優れていますが、現時点ではサポートは基本的にゼロです。
遅いindexOf / lastIndexOf関数を置き換える方法を考えていたのは久しぶりです。
上位の回答を見て、パフォーマンスの高い方法がすでに見つかりました。それらから私が選んだcontains
、@ Damir Zekicが投稿し関数の中で最速の。しかし、それはまた、ベンチマークが2008年からのものであり、そのため古くなっているとも述べています。
私もを好みますwhile
がfor
、特定の理由ではなく、forループを使用して関数の記述を終了しました。それは、while --
。
実行中に配列の両側をチェックすると、反復がはるかに遅くなるのではないかと気になりました。どうやらそうではないので、この関数は上位投票の関数より約2倍高速です。もちろん、ネイティブよりも高速です。これは、検索している値が配列の先頭にあるのか末尾にあるのかがわからない、現実の環境におけるものです。
値を持つ配列をプッシュしたことがわかっている場合は、おそらくlastIndexOfを使用するのがおそらく最善の解決策ですが、大きな配列を移動する必要があり、結果が至る所にある場合、これは物事を高速化する確実な解決策になる可能性があります。
双方向の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');
性能試験
http://jsperf.com/bidirectionalindexof
テストとして、100kエントリの配列を作成しました。
3つのクエリ:配列の最初、中央、最後。
これも面白いと思い、パフォーマンスをテストしてください。
注:ご覧のとおりcontains
、indexOfおよびlastIndexOfの出力を反映するように関数を少し変更しました(true
つまりindex
、基本的にとfalse
で-1
)。それはそれを害するべきではありません。
配列プロトタイプバリアント
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');
この関数は、trueまたはfalseを返すように簡単に変更したり、オブジェクト、文字列、またはそれが何であっても返すことができます。
そしてここにwhile
バリアントがあります:
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');
これはどのようにして可能ですか?
配列に反映されたインデックスを取得する単純な計算は非常に単純で、実際のループ反復を実行するよりも2倍速いと思います。
以下は、反復ごとに3つのチェックを行う複雑な例ですが、これはコードの速度低下を引き起こすより長い計算でのみ可能です。
http://jsperf.com/bidirectionalindexof/2