5

だから私は配列をシャッフルすることについて読んでいました。そして、私はこのスクリプトに出くわしました:

shuffle = function(o){ //v1.0
    for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};

よく見ると、for何もありません{}!しかし、それは魔法のように機能しています。私はそれがどのように機能するかを知りたいと思っています。(そしてコンマの束も。)

4

6 に答える 6

11

続くのfor ()はどのステートメントでもかまいません。中かっこを使用したものでも、単一の式でも、空の式でもかまいません。for (...);と同等for (...) {}です。当然、これは自然に終了するforループと組み合わせてのみ使用する必要があります。そうしないと、手に無限ループが発生します。

カンマは事実上2年生のセミコロンです。それらはほとんど別々のステートメントを作成しますが、forループで機能します(そして他の場所で;これはそれらの非常にずさんな定義です)。

for (
     // initialisation: declare three variables
     var j, x, i = o.length;
     // The loop check: when it gets to ``!i``, it will exit the loop
     i;
     // the increment clause, made of several "sub-statements"
     j = parseInt(Math.random() * i),
     x = o[--i],
     o[i] = o[j],
     o[j] = x
)
    ; // The body of the loop is an empty statement

これは、次のように、より読みやすい形式で表すことができます。

for (
     // initialisation: declare three variables
     var j, x, i = o.length;
     // The loop check: when it gets to ``!i``, it will exit the loop
     i;
     // note the increment clause is empty
) {
     j = parseInt(Math.random() * i);
     x = o[--i];
     o[i] = o[j];
     o[j] = x;
}

whileループとして、それは次のようになります。

var j, x, i = o.length;
while (i) {
     j = parseInt(Math.random() * i);
     x = o[--i];
     o[i] = o[j];
     o[j] = x;
}
于 2012-06-13T04:05:29.860 に答える
4

すべてのコンピューティングは、{}を必要としない単一のステートメントに対して同じステートメントに含まれていますが、このステートメントにも含まれています。(最後に文ターミネーターが使用されます)これは、次のステートメントがforステートメントに属していないことを意味します。論理が何であれ、それはステートメントについても同じです。

  for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);


  for(var j, x, i = o.length;// Initialization
  i;// Work until i is zero
 j = parseInt(Math.random() * i),
  x = o[--i], o[i] = o[j], o[j] = x);//Here he is    computing his logic
于 2012-06-13T04:01:51.200 に答える
4

まず、このようなループは非常に読みにくく、多くの混乱を引き起こすため、悪いスタイルと見なされていることに注意してください。これは、最適化がうまくいかなかった典型的な例です。

仕様を見ると、その後にステートメントfor(...)が続く必要があることがわかります。ブロックを含む任意のステートメントにすることができます。したがって、これらはすべて有効です。

for (...)
    foo;  // expression statement

for(...)
    {
       // block statement
    }

for(...)
   if(...) // If statement
      foo;

、 そしてもちろん

for (...)
    ;

;」は空のステートメントなので。何もしませんが、for(...);構文的に有効にするのに十分です。

さて、コンマについて。括弧の内容は、セミコロンで区切られた3つの式(それぞれオプション)でなければならないことに注意してください。カンマ区切りの式のリストを含め、ほとんど「すべて」が式と見なされます。あまり知られていませんが、これらはforループ内だけでなく、基本的にJSのあらゆる場所で機能します。それらは単に次々に評価されます。

だから、あなたのループはそのように書き直すことができます

shuffle = function(o) {
    var j, x, i = o.length;
    while (i) { // for-loops are just while-loops in disguise
        j = parseInt(Math.random() * i), // even better: replace , by ;
        x = o[--i],
        o[i] = o[j],
        o[j] = x;
    }
    return o;
};

また、x = o[--i]と書く必要がありますi--; x = o[i]

于 2012-06-13T04:51:41.120 に答える
1

すべてが1行になっている場合は、角かっこは必要ありません。多くの場合、括弧内の3番目のセクションにはi++、またはそのようなものが表示されます。実際、そこではさまざまなことができます。その3番目のセクションにすべてを詰め込める場合は、forループの本体も必要ありません。

for (first section; second section; third section);

最初のセクション

変数は宣言され、初期化されます。これらの変数は、ループのスコープに含まれています。

2番目のセクション

これは、ループの各パスでチェックされる条件です。

3番目のセクション

ループを通過するたびに実行されるコード。変数をインクリメントするのと同じくらい単純な場合もあれば、構文が正しい限り、行に収まるものなら何でも複雑な場合もあります。

于 2012-06-13T04:00:32.967 に答える
1

ループを正しく読み取れなかったようです。

この場合、評価はforループの条件内で行われます。

したがって、forループには3つの部分があります

for (initial variables; end cases; what to do every iteration)

関数に渡された初期のものと使用法oを定義し、エンドケースを定義してから、反復ごとに何かを計算します。最後にo、新しい値があり、それが返されます。

于 2012-06-13T04:00:39.647 に答える
0

すべての作業は、実際にはforステートメントの範囲内で行われています。ループの明示的な本文はないため;、最後のは本文が空のステートメントであるとだけ言っています。

,コンマ)演算子は、式を左から右に評価し、右端の値を返します。

ループは基本的に次と同等です。

for(var j, x, i = o.length; i > 0;)
{
    j = parseInt(Math.random() * i--);
    x = o[i];
    o[i] = o[j];
    o[j] = x
} 
于 2012-06-13T04:05:21.203 に答える