4

論理的でWeb開発者が理解できる、配列内のアイテムを見つけるための最も効率的な方法は何でしょうか。

私はこのコードに出くわしました:

var inArray = function(a, b, c, d) {
    for (c in b) d |= b[c] === a;
    return !!d
};

正常に動作します。誰かが私にコードを説明してもらえますか?私はまた、私のものを複製にするかもしれないまったく同じ質問
に出くわしました。しかし、私の本当の質問は、上記のコードの説明と、ビット単位の演算子が使用されている理由にあります。 また、配列内のアイテムのインデックスを取得するためのforループまたは反復なしの方法はありますか?

4

4 に答える 4

5
var inArray = function(a, b, c, d) {
    for (c in b) d |= b[c] === a;
    return !!d
};

それはいくつかのひどいコードであり、あなたはそれから逃げるべきです。ここではビット演算子は完全に不要であり、cパラメーターでdあることはまったく意味がありません(Raymond Chenが指摘したように、コードの作成者はローカル変数を宣言するための安全なスペースにそれを行った可能性があります-問題はtruedコードが突然壊れ、余分なパラメーターが宣言を一瞥することで得られる理解の感覚を破壊します)。

コードについて説明しますが、最初に、より良いオプションがあります。

function inArray(arr, obj) {
    for (var i = 0; i < arr.length; ++i) {
        if (arr[i] === obj) {
            return true;
        }
    }
    return false;
}

これは、実際の配列である配列に依存することに注意してください。for (k in arr)タイプループを使用して、すべてのオブジェクトに一般化することができます。


とにかく、説明に移ります:

for (c in b) d |= b[c] === a;

これは、b(に格納されているc)のすべてのキーについて、b[c] === a。つまり、配列に対して線形スキャンを実行し、各要素をに対してチェックしていますa

d |= valビット単位またはです。でハイになっているビットは、でハイにval設定されdます。これは、JSよりもビットが公開されている言語で説明するのが簡単ですが、簡単に説明します。

10011011
01000001
--------
11011011

これは、個々のビットを他の値の同じ位置ビットとOR演算するだけです。

ここでの悪用の理由は、コードを複雑にし、奇妙な暗黙のキャストに依存しているためです。

x === yブール値を返します。ビット単位の式で使用されているブール値はほとんど意味がありません。しかし、何が起こっているのかというと、ブール値がゼロ以外の値に変換されているということです(おそらく1)。

同様に、なりundefinedますd。これは、ビット単位のものdにキャストされることを意味します。0

0 | 0 = 0、しかし0 | 1 = 1。だから基本的にそれは栄光です:

for (c in b) d = (d || (b[c] === a));

それに関して!!xは、ブールに何かをキャストするために使用されます。 !xxを取り、暗黙的にブール値にキャストしてから無効にします。その後、余分な!ものはそれを再び否定します。したがって、暗黙的にブール値にキャストしている可能性があります(!!xtrueであるということは、xが少なくとも大まかにtrue(、、1など"string")であることを意味!!x、少なくとも大まかにfalse(、、など)であることを意味します。x0""


この回答は、さらにいくつかのオプションを提供します。ただし、これらはすべてネイティブにフォールバックすることを目的としているためindexOf、スクリプトランドでコーディングできるものよりもほぼ確実に高速になります。

于 2012-12-30T19:18:40.667 に答える
2

このコードはかなり貧弱に書かれていて、ほとんど読めません。私はそれを「素晴らしい」とは見なしません...

これが書き直されたバージョンで、うまくいけばもっと読みやすくなります。

function inArray (aElt, aArray) {
  var key;
  var ret = false;
  for (key in aArray)
    ret = ret || (aArray[key] === aElt);
  return ret;
}

forループは、それを行うための最も自然な方法のようです。再帰的に行うこともできますが、ここでの最も簡単なアプローチとは思えません。

于 2012-12-30T19:04:22.663 に答える
2

論理的でWeb開発者が理解できる、配列内のアイテムを見つけるための最も効率的な方法は何でしょうか。

ネイティブメソッド、haystack.indexOf(needle) !== -1またはできるだけ早く戻るループメソッドのいずれか

function inArray(needle, haystack) {
    var i = haystack.length;
    while (i) if (haystack[--i] === needle) return true;
    return false;
};
于 2012-12-30T19:19:12.010 に答える
2

再帰バージョンを要求しました

var inArray = function(arr, needle, index) {
    index = index || 0;
    if (index >= arr.length)
        return false;
    return arr[index] === needle
         ? true
         : inArray(arr, needle, index + 1);
}

console.log(inArray([1,5,9], 9));
于 2012-12-30T20:03:37.660 に答える