代码之家  ›  专栏  ›  技术社区  ›  Hexagon Theory

关于JavaScript for()循环巫毒

  •  14
  • Hexagon Theory  · 技术社区  · 17 年前

    在相当长的一段时间里,我的印象是 for 循环可能存在 格式如下:

    for (INITIALIZER; STOP CONDITION; INC(DEC)REMENTER)
     {
        CODE
     }
    

    肯定 事实并非如此;看看 Fisher-Yates Shuffle

    shuffle = function(o)
     {
        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;
     };
    

    就在那里 内部

    9 回复  |  直到 17 年前
        1
  •  14
  •   Phil H    17 年前
    shuffle = function(o){
         for (
              var j,                // declare j
                  x,                // declare x
                  i = o.length;     // declare i and set to o.length
              i;                    // loop while i evaluates true
              j = parseInt(Math.random() * i), // j=random number up to i
                x = o[--i],         // decrement i, and look up this index of o
                o[i] =  o[j],       // copy the jth value into the ith position
                o[j] = x            // complete the swap by putting the old o[i] into jth position
              );
         return o;
         };
    

    这是从i开始的,i等于位置的数量,每次交换卡i和j,其中j是一些随机数,每次直到i,根据算法。

    它可以写得更简单,没有令人困惑的逗号集,真的。

    顺便说一下,这是

     for(var key in arr) {
          value = arr[key]);
     }
    

    但要小心,因为这也会循环遍历对象的属性,包括传入数组对象时。

        2
  •  11
  •   Matthew Crumley    17 年前

    for循环(不是for in循环)的通用格式为

    for ( EXPRESSION_1 ; EXPRESSION_2 ; EXPRESSION_3 ) STATEMENT
    

    第一个表达式_1是 通常 用于初始化循环变量,表达式_2是循环条件,表达式_3是循环条件 递增或递减操作,但没有规则规定它们必须这样做。它相当于以下while循环:

    EXPRESSION_1;
    while (EXPRESSION_2) {
        STATEMENT
        EXPRESSION_3;
    }
    

    逗号只是将两个表达式组合成一个表达式的运算符,其值是第二个子表达式。它们用于for循环,因为每个部分(用分号分隔)都需要是一个表达式,而不是多个语句。实际上没有理由(除了可能在文件中节省一些空间)编写这样的for循环,因为这是等效的:

    shuffle = function(o) {
        var j, x;
        for (var i = o.length; i > 0; i--) {
            j = parseInt(Math.random() * i);
            x = o[i - 1];
            o[i - 1] = o[j];
            o[j] = x;
        }
        return o;
    };
    
        3
  •  8
  •   Yuliy    17 年前

        4
  •  7
  •   slim    17 年前

    你引用的代码在我看来是模糊的。有更清晰的方法来编写相同的功能。

    然而,你的理解是非常正确的。下面是完全相同的代码,除了空格和注释。

    for (
         // Initializer
         var j, x, i = o.length;
         // Continue condition
         i;
         // Operation to be carried out on each loop
         j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x
     )
     // empty body, equivalent to { }
     ;
    

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

    while(i > 0) 而不是 while(i) --i 变成 i-- 在另一行。

    除了可读性之外,没有理由存在()。这两个是等效的:

    { // this block is to scope int i
       int i=0;
       while(i<100) {
           myfunc(i);
           i++;
       }
    }
    
    for(int i=0; i<100; i++) {
        myfunc(i);
    }
    

        5
  •  4
  •   Milan BabuÅ¡kov    17 年前

    for循环的语法为:

    for (pre-block; condition; post-loop-block)
        loop-block;
    

    首先,执行预块,定义各种变量。

    1. 检查条件
    2. 执行循环块
    3. 从1开始重复。
        6
  •  1
  •   OscarRyz    17 年前

    那句话确实符合你最初的格式。

    事实证明,您可以使用“,”(逗号)在每个句子中添加多个句子

    因此:

    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,                           //INITIALIZER(s)
             x,
             i = o.length;
    
         i;                               // STOP CONDITION ( i ) 
    
         j = parseInt(Math.random() * i), // INC(DEC)REMENTER
         x = o[--i],
         o[i] = o[j],
         o[j] = x);  // CODE ( ; ) 
    

    如您所见,它完全符合您的初始格式。

        7
  •  1
  •   Peter Richards    17 年前

    他们几乎只是将循环体移动到递增部分。您可以将for循环重新编写为while循环,以了解它在做什么:

     shuffle=function(o) {
        var j; //Random position from 0 up to the current position - 1
        var x; //temp holder for swapping positions
        var i=o.length; //current position
        while(i>0) { // Loop through the array
            j = parseInt(Math.random()*i); //get a lower position
            x = o[--i]; // decrement the position and store that position's value in the temp var
            o[i]=o[j]; // copy position j to position i
            o[j]=x; // copy the temp value that stored the old value at position i into position j
        }
        return o;
    }
    

    前三个变量是展开的initialzier,while中的check是停止条件,while的主体是for的incrementer部分中完成的内容。

        8
  •  1
  •   Scott Evernden    17 年前

    这一点可以追溯到C语法——javascript从C语法中窃取了很多东西。主要的技巧是逗号运算符,除了循环之外,它几乎不出现在任何其他地方

        9
  •  0
  •   Misko    17 年前