Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regarding JavaScript for() loop voodoo

Tags:

javascript

I was for quite some time under the impression that a for loop could exist solely in the following format:

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

This is, however, most definitely not the case; take a look at this JavaScript implementation of the 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;
 };

This little snippet completely blows my mind; how in the world is so much going on inside a simple for loop declaration? I mean... it doesn't even open a brace! All of the magic is being done right there inside the for statement. It'd be absolutely wonderful if somebody could provide a relatively thorough explanation as to how in the world this voodoo is doing what it does. Much appreciated in advance.

like image 229
Hexagon Theory Avatar asked Mar 23 '09 18:03

Hexagon Theory


2 Answers

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;
     };

This is starting with i equal to the number of positions, and each time swapping the cards i and j, where j is some random number up to i each time, as per the algorithm.

It could be more simply written without the confusing comma-set, true.

By the way, this is not the only kind of for loop in javascript. There is also:

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

But be careful because this will also loop through the properties of an object, including if you pass in an Array object.

like image 139
Phil H Avatar answered Oct 28 '22 01:10

Phil H


The generalized format of a for loop (not a for-in loop) is

for ( EXPRESSION_1 ; EXPRESSION_2 ; EXPRESSION_3 ) STATEMENT

The first EXPRESSION_1 is usually used to initialize the loop variable, EXPRESSION_2 is the looping condition, and EXPRESSION_3 is usually an increment or decrement operation, but there are no rules that say they have to behave like that. It's equivalent to the following while loop:

EXPRESSION_1;
while (EXPRESSION_2) {
    STATEMENT
    EXPRESSION_3;
}

The commas are just an operator that combines two expressions into a single expression, whose value is the second sub-expression. They are used in the for loop because each part (separated by semicolons) needs to be a single expression, not multiple statements. There's really no reason (except maybe to save some space in the file) to write a for loop like that since this is equivalent:

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;
};
like image 30
Matthew Crumley Avatar answered Oct 28 '22 00:10

Matthew Crumley