So I was reading about shuffling an array. And then I came across this script:
shuffle = function(o){ //v1.0
for(var j, x, i = o.length; i; j = parseInt(
If it's all on one line, no brackets are necessary. A lot of times in that third section inside the parenthesis, you just see i++
, or something like that. Really, you can do many different things there. If you are able to pack everything in that third section, you don't even need a body for the for
loop.
for (first section; second section; third section);
First section
Variables are declared and initialized. These variables are contained by the scope of the loop.
Second section
This is the condition checked with each pass of the loop.
Third section
Code that runs after each pass through the loop. It can be as simple as incrementing a variable, and as complex as... well, anything you can fit on the line, as long as syntax is correct.
First, I'd like to note that such a loop is considered bad style, since it's very unreadable and causes a lot of confusion. This is a typical example of optimization gone wrong.
Looking at the specs, you'll find that for(...)
must be followed by a statement.
It can be any statement, including blocks. So all of these are valid:
for (...)
foo; // expression statement
,
for(...)
{
// block statement
}
,
for(...)
if(...) // If statement
foo;
, and of course
for (...)
;
since ";
" is the empty statement. It does nothing, but it's enough to make for(...);
syntactically valid.
Now, for the commas. Note that the contents of the parens must be three expressions, (each of them optional), separated by semicolons. Pretty much "everything" qualifies as expressions, including comma-separated lists of expressions. Though little known, these work basically everywhere in JS, not only in for
loops. They are simply evaluated one after the other.
So, your loop can be rewritten like so
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;
};
Also, x = o[--i]
should be written as i--; x = o[i]
.
Looks like I didn't read the loop correctly.
In this case, the evaluations are happening inside the conditions of the for loop.
So a for loop has three parts
for (initial variables; end cases; what to do every iteration)
You define some initial stuff and use o
which was passed into the function, define an end case, and then compute something every iteration. At the end, o
has a new value and it gets returned.
What follows the for ()
can be any statement; that can be something with curly braces, or it can be a single expression, or it can be an empty expression. for (...);
is equivalent to for (...) {}
. Naturally, this should only be used in conjunction with a for-loop which will terminate naturally, or you'll have an infinite loop on your hands.
The commas are effectively second-grade semicolons; they make for mostly-separate statements, but which will work in a for loop (and elsewhere; this is a very sloppy definition of them).
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
This could be put in a more readable form as:
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;
}
As a while loop, that could be:
var j, x, i = o.length;
while (i) {
j = parseInt(Math.random() * i);
x = o[--i];
o[i] = o[j];
o[j] = x;
}
All the work is actually being done within the parens of the for
statement. There is not explicit body for the loop so the ;
at the end just says that the body is an empty statement.
The ,
(comma) operator evaluates expressions from left to right, and returns the value of the right-most.
The loop is basically equivalent to:
for(var j, x, i = o.length; i > 0;)
{
j = parseInt(Math.random() * i--);
x = o[i];
o[i] = o[j];
o[j] = x
}
Every computing is in same statement for single statement we dont need {} but also in this statement ; (sentence terminator is used in the end) it means next statement does not belong to for statement. Whatever logic is it is in same for statement.
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