7

ユーザーがフォーム フィールドに入力した入力文字列を確認するとします。可能な値のリストに対してこの入力をチェックする最速の方法はどれですか?

次の例ではjQueryを使用しています。

最初の方法:使用||

if (input == "firstValue" || input == "secondValue" || ... ) {
    ...
}

2番目の方法:使用inArray()

if ($.inArray(input, array) >= 0) {
    ...
}

これら2つの方法に大きな違いはありますか?

4

4 に答える 4

17

最速ではなく、最も読みやすい方法が必要です。これはin_array()(JavaScript: array.indexOf(value) >= 0) 2 つまたは 3 つを超える値の場合です。

パフォーマンスの違いはごくわずかです。関数呼び出しと配列の作成には確かにいくらかのオーバーヘッドがありますが、ファイル アクセス、データベース アクセス、ネットワーク アクセスなどの高価な操作と比較すると問題ではありません。したがって、最終的に誰も違いに気付かないでしょう。 .

以下は短いベンチマークで、それぞれ 100 万回の反復があります。

5.4829950332642 - in_array, the array is recreated everytime
2.9785749912262 - in_array, the array is created only once
0.64996600151062 - isset(), the array way created only once and then the values were turned to keys using array_flip()
2.0508298873901 - ||

したがって、最速でありながら非常に読みやすい方法はこれです。一度だけ作成して$arr度も使用しない限り、これは必要なく、そのまま使用できます。in_array()

$arr = array_flip(array('your', 'list', 'of', 'values'));
if(isset($arr[$value])) ...

JavaScript を要求した場合 (この場合、これらの接頭辞を削除してください! )、最善の解決策は次を使用することです。$Array.indexOf()

['a', 'b', 'c'].indexOf(value) >= 0

ただし、すべてのブラウザーが既に をサポートしているわけではないArray.indexOf()ため、たとえばUnderscore.jsの関数を使用することをお勧めします。

_.contains(['a', 'b', 'c'], value)

jQuery には、このための関数もあります。

$.inArray(value, ['a', 'b', 'c'])

最も速い方法はオブジェクトとin演算子を使用することですが、オブジェクト定義は配列定義よりも読みにくくなります。

value in {'a':0, 'b':0, 'c':0}

さまざまなソリューションの JSPerf ベンチマークは次のとおりです。ループ。

于 2012-05-07T08:42:19.937 に答える
4

答えは、場合によります...

可能性が少ない場合は、 を使用しますif (a || b || c)

おそらく最大10個ある場合は、使用しますArray.indexOf()

上記の 2 つの推奨事項については、実際のパフォーマンスではなく、読みやすさに基づいて選択する必要があることに注意してください。

それ以上 (多数) ある場合はObject、値と等しいキーで を使用すると、 を使用できますif (myVar in myKeyObj)。これにより、最悪のO(log n)パフォーマンスが得られるはずです。

于 2012-05-07T08:42:06.523 に答える
2

通常、javascript を実行する場合、パフォーマンスはそれほど問題ではなく、通常は答えにくい質問です。

このサンプルでは、​​ソリューション間の主な違いはスケーリングです。最初のソリューションは、常に所定の量の比較を行いますが、inArray ソリューションは、より多くの値がある場合により多くの比較を行うため、スケーリングが悪化します。

ただし、私はまだ inArray を使用しますが、99.99% の確率でパフォーマンスは問題になりません。コードを維持しやすくすることは、より重要です。

于 2012-05-07T08:42:18.577 に答える
2

ほとんどの言語では、inArray() は次のように実装されています。

function inArray(needle, haystack) {
  for (i = 0; i < length; i++) {
    if (haystack[index] == needle) {
      return true;
    }
  }

  return false;
}

そのループを展開すると、最終的には次のようになります

if (haystack[0] == needle) {
  return true;
} 
if (haystack[1] == needle) {
  return true;
}
if (haystack[3] == needle) {
  return true;
}
// and so on

に凝縮することができます

if (haystack[0] == needle || haystack[2] == needle || … ) {
  return true;
}

フードの下で起こっていることを変えることなく。


そういうものを繰り返し調べなければならない場合は、地図を知ることをお勧めします。それ以外の

var haystack = ['hello', 'world', 'how', 'is', 'life'];
if (inArray("life", haystack)) {
  // …
}

あなたがやる

var haystack = {'hello' : true, 'world' : true, 'how' : true, 'is' : true, 'life' : true};
if (haystack["life"]) {
  // …
}

チェックする要素が多いほど、配列と比較してマップのパフォーマンスが向上します。

于 2012-05-07T08:55:07.543 に答える