I am implementing HTML5 drag and drop using JavaScript, and I have found some sample code that is actually working. But this one piece of code doesn't make sense to me. What is this snippet of code doing?
// fetch FileList object
var files = e.target.files || e.dataTransfer.files;
// process all File objects
for (var i = 0, f; f = files[i]; i++) {
}
I am confused by the FOR loop. I understand it's basic use:
for (var i = 1; i < 5; i++)
But how does this work? What is var i = 0, f?
The initialization expression var i = 0, f is declaring two variables, i and f. The i is initialized to zero, while the f is left uninitialized. Then, for each iteration through the loop, the value at position i in the files array is assigned to f. This result of this assignment is evaluated as the loop conditional. At the end of each iteration the integer value of i is incremented by one.
At a high level this just iterates over values in the files array, assigning each to f for use in the loop body. Once an index in the files array is reached that does not have a truthy value the loop is exited. An assumption is made here that all valid values in the files array will be truthy.
Related
I have an assignment to count repeated strings base on a Heap's Algorithm Permutation.The first thing I want to do is output the swapped strings, I found this code from jake's answer Can someone please help me understand recursion within this code in a loop? The output of this function are swapped strings.
function permAlone(string) {
var arr = string.split(''), // Turns the input string into a letter array.
permutations = []; // results
function swap(a, b) {
debugger; // This function will simply swap positions a and b inside the input array.
var tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
function gen(n) {
debugger;
if (n === 1) {
var x =arr.join('');
permutations.push(x);
} else {
for (var i = 0; i != n; i++) { // how does this loop executes within the call stack?
gen(n - 1);
debugger;
swap(n % 2 ? 0 : i, n - 1); // i don't understand this part. i understand the swap function, but I don't get how indexes are swapped here
}
}
}
gen(arr.length);
return permutations;
}
permAlone('xyz'); // output -> ["xyz","yxz","zxy","xzy","yzx","zyx"]
I have been experimenting it on debugger but still can't get what's happening.
I'm not sure what you mean by
understand recursion within this code in a loop
If you mean you want to see the algorithm in a loop form rather than a recursion version you can see them one by side in pseudocode in the wikipedia page here.
For your questions within the code:
how does this loop executes within the call stack?
You are right to refer to the call stack, and this is a general question regarding recursion. If you don't understand how recursion works with the stack you can refer to this really nice and simple video that demonstrates recursive calls using factorial calculation in java (start around min 4:00).
The line you look at is no different than any other line in the recursive function. We start by defining i and assigning the value 0 to it. We continue to check if it satisfies the condition of the for loop. If it does we step into the loop and execute the first line inside the loop which is the recursive call. Inside the recursive call we have a new stack frame which has no knowledge of the i variable we defined before executing the recursive call, because it is a local variable. So when we get to the loop in the new call we define a new variable i, assigning it 0 at first and incrementing it as the loop repeats in this stack frame/call instance. When this call finishes we delete the stack frame and resume to the previous stack frame (the one we started with) where i=0 still, and we continue to the next line.
All the calls have access to the arr and permutations variables since the function is defined in the same scope as the variables (inside the function permAlone) so within each call - no matter what the stack frame we are in, the changes made to those are made to the same instances. That's why every push done to permutations adds to the existing results and will be there when the function returns the variable at the end.
i don't understand this part. i understand the swap function, but I don't get how indexes are swapped here
Indexes are not swapped here. It is merely a call for the swap function with the correct indices.
swap(n % 2 ? 0 : i, n - 1);
is just
swap(a, b);
with
a = n% 2 ? 0 : i;
b = n - 1;
If the a part is what confuses you, then this is a use of the ternary operator for conditional value. That is, it's symbols used to form an expression that is evaluated differently according to the circumstances. The use is by
<<i>boolean epression</i>> ? <<i>value-if-true</i>> : <<i>value-if-false</i>>
to evaluate the above, first <boolean expression> is evaluated. If it's value it true then the whole expression is evaluated as <value-if-true>. Otherwise, the whole expression is evaluated as <value-if-false>.
In the code itself, for a, n % 2 is the boolean expression - js divides n by 2 and takes the remainder. The remainder is either 1 or 0. js implicitly converts those to true and false respectively. So if n is odd we get
a = 0
and if it's even we get
a = i
as the algorithm requires.
I have never seen a JavaScript loop such as this for( ; i-- ; ), used in the code:
uid: function (len) {
var str = '';
var src = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var src_len = src.length;
var i = len;
for (; i--;) {
str += src.charAt(this.ran_no(0, src_len - 1));
}
return str;
}
I understand the behavior, but I would like it if somebody could share some insights about this type of for loop.
This is a syntax of the for-loop construction:
for ([initialization]; [condition]; [final-expression])
statement
In your case for (; i--;) {:
no variables are initialized, because var i = len; inintialized earlier, so it's not needed.
condition part will be truthy until i becomes 0 then loop will terminate. i-- is executed on before each iteration, and due to -- operator it will eventually become 0, so it's falsy, and loop will stop.
since i is decremented in condition part of the loop, final-expression is not needed too. Another way to put it: since i is not used inside the loop, it does not matter whether we decrement it before each loop iteration or after each loop iteration.
That being said, it's better to avoid writing loops like above, as it's pretty confusing and hard to read. Prefer traditional for-loops notation.
From MDN - for - Optional for expressions:
All three expressions in the head of the for loop are optional.
You don't have to specify all three expressions in for loops. For example, for (;;) is a common wa of writing infinite loop.
In your case, while(i--) would have done the same, there is no good reason to write for (; i--;).
I'd also note that for(var i=len;i>=0;i--) is more robust - it protects you from the case len is negative.
This could be rewritten to
uid: function (len) {
var str = '';
var src = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var src_len = src.length;
var i = len;
while (i >= 0) {
str += src.charAt(this.ran_no(0, src_len - 1));
i = i - 1;
}
return str;
}
The for statement creates a loop that consists of three optional
expressions.
Javascript consider 0 == false that's why in the case you presented the loop will run until the i variable became zero. It will loop as many times as the src string size.
Note: i-- uses the variable value then decrements it. Take a look at the following situation:
for(;i--;) { // i = length in the condition
// i === length - 1 here. It will not overflow the array
}
for(;i--;) { // i = 1
// i === 0 here. It will be the last loop
}
for(;i--;) { // i == 0 == false
// Not executed
}
There is nothing wrong.
for(`INIT`;`TEST`;`ACTION`)
{
`WORK`;
}
The INIT (initialization) can be done outside the loop.
var i=0;
for(;i<=100;i++)
//do something
The TEST part yield a result that is either true or false. Now in this case value of i is tested. Until it becomes zero this works.
The ACTION part is generally used to change the loop variable. But you can leave it also or probably add it to the TEST section like it is done here.
Look this examples are going to clear your idea
var i=0;
for( i++; i++; i+=j); //No body
var i=0;
for(;;); //an infinite loop
var i;
for(i=-4;i;i++);//
Even sometimes WORK is placed in ACTION.
Example:
factorial of x
for(var i=1,ans=1;i<=x;ans=ans*(i++));
Which can be written this way also-
var ans=1;
for(var i=1;i<=x;i++)
ans=ans*i;
NOTE: You can write whichever way you want. It doesn't matter as long as you have written the code properly. Get used to this kind of form you will see them a lot.
Though, it is better to write sometimes in compact form , but remember you should keep the readability.
That's just for loop. Before the first semicolon the variable used in the loop is usually declared. But in this case the variable, the variable used in the loop is declared earlier:
var i = len;
^^^
for (; i--;) {...
So there is no need to redeclare.
After the first semicolon, there is a condition for the loop to run (i.e. i<6, i>3, etc). If condition returns false, or 0, the loop is exited. In this case, the loop will be broken out when i is 0. It happens eventually, because -- after i decrements it, and therefore there is no need for the expression, which is the place after the second semicolon is reserved for.
The first parameter of the for loop has already been defined, so the initial comma is there to delimit it's place in the parameter list.
I'm trying to track down a bug in the ember.js source code when I came across this for loop:
for (operationIndex = rangeStart = 0, len = this._operations.length; operationIndex < len; rangeStart = rangeEnd + 1, ++operationIndex) {
The constituent parts are broken down to what looks like multiple declarations, e.g.:
operationIndex = rangeStart = 0, len = this._operations.length
Can anyone explain what this declaration does and can I assume that the loop counter is initilaized to 0 given the above expression?
Taking this "template":
for (A; B; C)
There are three parts in the loop declaration. The first part (A) is executed once before the actual loop begins, and is usually used to declare the loop iterator but can be used for other things.
The second part (B) is the stop condition: it's being evaluated in the beginning of each iteration, and when returning false, the loop ends.
The third part (C) is executed in the end of each iteration and usually used to change the loop iterator so the loop will end at some point.
To focus again on your specific question, the comma is just used to separate two variable assignments.
The below code works fine in javascript
var items = [1,2,5]
for (var i = 0, item; item = items[i]; i++) {
console.log(item = items[i]);
}
OUTPUT : 1 2 5
I am not sure how this program works successfully
The forth item is undefined and what will happen in the last iteration.
Can we able to create a similar function in Java ?
items[3] at the end how it will be handled in the above function?
Two key things to start with:
First, in JavaScript, whenever you try to retrieve the value of an object property that doesn't exist (including an array entry), the result of the retrieval is the value undefined.
Second, when you use a value like a flag, as in an if statement or the "test" part of a for (or any other loop), etc., JavaScript with "coerce" whatever value you used to be boolean. [This is different from (say) Java, which requires that you only use boolean variables as that sort of flag.] Because JavaScript does this and it comes up a lot, we use the terms "truthy" (coerces to true) and "falsey" (coerces to false) to categorize values. The "falsey" values are 0, "", NaN, null, undefined, and of course false; all other values are truthy.
Okay, armed with that information, let's look at your loop:
The forth item is undefined and what will happen in the last iteration.
There are only three iterations. A for statement is made up of three expressions separated with ;, and a loop body. The expressions are the initialization, the test, and the increment:
// /--------------------------------initialization
// | /--------------- test
// | | /--- increment
// vvvvvvvvvvvvvvv vvvvvvvvvvvvvvv vvv
for (var i = 0, item; item = items[i]; i++) {
The loop is evaluated like this:
Do the initialization
Do the test
If the test was false, terminate
Do the body
Do the increment
Go back to step 2
The "test" part of your for loop is item = items[i], which is an assignment. The value of an assignment expression is the value being assigned. So when i is 3, that assignment is item = items[3] which is effectively item = undefined. That assignment has the value undefined, which is a falsey value, so the body of the loop isn't run a fourth time.
Can we able to create a similar function in Java ?
Yes, it looks almost identical other than that with Java, you use a type with the variables, and you can't use (just) the item = items[i] thing for the "test" part of the for (for the same reason you get an exception below).
items[3] at the end how it will be handled in the above function?
You don't have any function in your question. After the loop, in JavaScript, accessing items[3] would give you undefined (see above). In Java, it result in an ArrayIndexOutOfBoundsException.
Side note: The = in this line is an assignment, not a comparison:
console.log(item = items[i]);
If you meant to compare them, do this:
console.log(item == items[i]);
...which will give you the output
true
true
true
Here is what happens in your loop:
1. i = 0; item = 1; i = 1;
2. item = 2; i = 2;
3. item = 5; i = 3;
4. item = undefined; --> breaks the loop
Notice, that if you'd have items = [0,1,2], your loop would never be executed.
The code works fine as you have assignment in the for loop condition check
During the first iteration item is undefined but it executes the loop without termination as you assign the first value of array to item and it is no more undefined
Try it with comparision operator as item == items[i], you will find your loop no more executes even once.
When it comes outside of array i.e. items[3] which returns undefined and thus temp goes undefined and terminates the loop as in javascript undefined, null, 0 and false all are same.
This function wont work in Java as it would complain that it requires condition not the assignment in for loop.
here is the function:
var M = [];
function haveComponents () {
var a = 0;
for (var n in this.M) a++;
return a > 0;
}
I would like to understand:
the construct of "for(var n in this.M)"; I'm used to a regular for loop and I'm not familiar with this construct.
how "this.M" fits into the code i.e. its purpose
generally speaking, what this function would likely be used for.
Thanks
There appears to be some missing code.
var M = [];
Assigns a new array to the variable M, which seems to be a global variable (but likely isn't, you just haven't shown enough code to properly determine the context).
haveComponents: function () {
That appears to be part of an object literal that assigns a function to a property called haveComponents.
var a = 0;
Creates a local variable a and when the code executes, assigns it a value of 0.
for (var n in this.M) a++;
Creates a local variable n and sequentially assigns it the name of an enumerable property of whatever this.M references. If this is the global object, M will be the array initialised above. If not, it may or may not be something else. You haven't shown any other assignment, or what this has been set to.
For each enumerable property of M (which includes its inherited properties), a will be incremented by one.
return a > 0;
}
Returns true if a is greater than zero.
An equivalent function is:
haveComponents: function () {
for (var n in this.M) {
// this.M has at least one enumerable property
return true;
}
// this.M has no enumerable properties
return false;
}
or for the purists:
haveComponents: function () {
var hasEnumerable = false;
for (var n in this.M) {
hasEnumerable = true;
break;
}
return hasEnumerable;
}
The function counts how many elements are in the M array.
The for in allows you to iterate object's enumerable properties , note that this is different from a for each behaviour where the iteration is over items rather tha properties. In javascript this translates into going into the prototype property names and list them as well, possibly resulting in unexpected result.
for(var n in this.M) this is a for-each loop, used to iterate over a set of values instead that by using conditions. It is used to iterate over properties of objects.
the this keyword refer to the owner of the function (whose is the haveComponents function), while M is a property of this
this function just, uselessly, counts elements in M to see if they are more than 0. Counting them is absolutely superfluous for this purpose though.
The for(var n in this.M) iterates through all of the elements of this.M, successively storing them in the variable n.
I have no idea what this.M is, that depends on where your code comes from.
In general, I would say that this code returns whether M is empty or not (and returns true if it is not empty).