In which order do nested For Loops run? - javascript

for(var i = 1; i<10; i++){
for(var j = 1; j<10; j++){
ss.getRange(j, j).setValue('Second Loop');
}
ss.getRange(i, i).setValue('First Loop');
}
In this example, I'm iterating through two For Loops. The results from the first loop should replace the result from the second loop because it comes after the second loop has set the values of the cell in the Google Sheet.
Yet this is the result that I get:
I sincerely appreciate your response.

see when the outer loop runs last time , then the inner loop overwrites all the existing cells but the last one statement executes and prints first loop

Consider the last iteration of i = 9 which would run like this
for(var j = 1; j<10; j++){
ss.getRange(j, j).setValue('Second Loop');
}
ss.getRange(9, 9).setValue('First Loop');
So the last iteration of the enclosing loop will first write "Second Loop" to all diagonals and after that write "First Loop" to the field (9,9).
Nested loops run in the order in which the enclosing loop is run.
i=1: j=1 -> j=2 -> j=3 -> ... -> j=9
i=2: j=1 -> j=2 -> ... -> j=9
i=3: ...
So for each i, every j is iterated.

Related

What's the difference between these two code?

while(todoList.children[0] !=null){
todoList.children[0].remove();
}
for(let i = 0 ; i<todoList.childElementCount ; i++){
console.log(i);
todoList.children[0].remove();
}
I have a list and it has 5 elements in it. I want to remove elements from it. If i try to reach lists element count it gives 5 value with no problem .When i use while loop it works but for loop just runs 3 times.
A better way would be to store the todoList.childElementCount first in a new variable, and use that variable in the terminating condition of for-loop.
Or if you do not want to store todoList.childElementCount in a new variable, then:
for(let i = todoList.childElementCount-1; i>=0 ; i--){
console.log(i);
todoList.children[0].remove();
}
todoList.children[0] is same as todoList.firstChild
while(todoList.children[0] !=null){
todoList.children[0].remove();
}
looks up if the todolist has ONE child, and if so, then it removes it.
for(let i = 0 ; i<todoList.childElementCount ; i++){
console.log(i);
todoList.children[0].remove();
}
looks up every single time HOW MANY childs there are and then removes the firstchild. So therefore it is not that performant.
It would be the same if code was:
let initialChildCount = todoList.childElementCount;
for(let i = 0 ; i < initialChildCount; i++){
console.log(i);
todoList.children[0].remove();
}
In your code you keep decreasing todoList.childElementCount therefore loop ends faster

How to set a button to execute a for loop?

My code starts on first item in the first array and iterate through the second array. If the first item in the first array is the same as the item in the second array the value is printed to the console. So in this snippet Nandos and KFC should print to console.
Then once the first item in the first array has been compared to all of the items in the second array we would move to the second item in the first array and compare it to all the items in the second array.
I want to execute the for loop once the button is clicked.
I tried to make the for loop a function and to execute the function once the button was clicked but nothing happened.
<button id="search">Search</button>
var restaurantsOne = ["Nandos", "King Rooster", "Chick-Fil-A", "Dominos", "KFC"];
var restaurantsTwo = ["Nandos","MacDonalds","Burger King","KFC","Pizza Hut"];
for (var i=0; i<=restaurantsOne.length; i++) {
for (var j=0; j<=restaurantsTwo.length; j++){
if (restaurantsOne[i] == restaurantsTwo[j]){
console.log(restaurantsOne[i]);
}
}
}
I would like the for loop to execute once the button was clicked
You haven't linked the button to the loop! Wrap the loop in a function and then add an 'onclick' handler to the button that references the loop function.
var restaurantsOne = ["Nandos", "King Rooster", "Chick-Fil-A", "Dominos", "KFC"];
var restaurantsTwo = ["Nandos","MacDonalds","Burger King","KFC","Pizza Hut"];
function compareArrays () {
for (var i = 0; i < restaurantsOne.length; i++) {
for (var j = 0; j < restaurantsTwo.length; j++){
if (restaurantsOne[i] == restaurantsTwo[j]){
console.log(restaurantsOne[i]);
}
}
}
}
<button id="search" onclick="compareArrays()">Search</button>
Also, it's worth mentioning that you should use i < restaurantsOne.length instead of i <= restaurantsOne.length because the array index starts from 0 and array[array.length] will actually refer to an index that doesn't exist.
ie.
restaurantsOne.length // 5
restaurantsOne[0] // Nandos
restaurantsOne[1] // King Rooster
restaurantsOne[2] // Chick-
restaurantsOne[3] // Dominoes
restaurantsOne[4] // KFC
restaurantsOne[5] // undefined

jquery $.each vs for loop (with async content)

What is the main difference between:
var test=[5,6,7,8,9];
$.each(test, function (i, num) {
setTimeout(function(){console.log('i: '+i+' '+num)},500);
});
for (var j = 0; j < test.length; j++) {
setTimeout(function(){console.log('j: '+j+' '+test[j])},500);
}
First loop outputs:
i: 0 5
i: 1 6
i: 2 7
i: 3 8
i: 4 9
Second loop outputs:
5 times 'j: 5 undefined'
I understand why the second loop does this, but not why $.each works 'as expected'
Thanks!
In the first snippet's behind the scene, for every iteration the call back that you have supplied will be called. That means, internally it will create a scope per iteration. That eventually becomes a cloure.
But in the second snippet. The initial scope will be used while the timeout's call back got triggered. So it is displaying that output. And you can make it work by using the following code,
for (var j = 0;j<test.length-1;j++) {
var scope = function(i) {
setTimeout(function(){console.log('j: '+i+' '+test[i])},500);
};
scope(j);
}

Nested Javascript for loops with break and label statements

I'm kinda new to Javascript and currently going over the book Professional Javascript for Web Developers and I came across this code which uses a break statement to exit the current loop and jump to a label named outermost.
Now I understand what break and labels do but I can't wrap my head around why the value ends up being 55 at the end?
Ok so the for loop with var i will loop 4 times then at 5 it breaks out to label:outermost and same with j so the first iteration i = 4 and j = 4 and num = 2. I guess this part confuses me.. at what point does the code stop. My first instinct if I were to code this from scratch is to have an outside variable and set the condition on that. But with the below code I don't get where the control structure lies and the final value. Appreciate any help or to be pointed in the right direction, thanks.
var num = 0;
outermost:
for (var i=0; i < 10; i++) {
for (var j=0; j < 10; j++) {
if (i == 5 && j == 5) {
break outermost;
}
num++;
}
}
alert(num);
This nested loop is emulating an odometer. i is the 10's digit, j is the 1's digit. Every time the 1's digit changes, num is incremented; at the start of each iteration, num contains the odometer's value.
The loop stops when both i and j are 5. At that point, the odometer would read 55, and that's what is in num.
When i was 0 to 4, the innermost loop is executed 50 times. When i = 5, the innermost loop is executed just 5 times until it reached i==5 && j==5 and jumped out. So it's total of 55 times.

how to create new callback function

In the code below I'm adding a callback function essentially to a list in a loop.
every Item in the list that I call the call back it will log >>item30
can you please tell me why? Is there a way create a new function() as the call back so
that it can log
item0
item1
item2
item3
item4
and so on .......
......
for (var j = 0 ; j < 30 ; j += 1) {
addThisThingtoList(function () {
console.log( "item" +j );
});
}
This only happens if your function addThisThingtoList() is using asynchronous behavior (like Ajax calls) and thus its callback is called some time later after the for loop has completely run its course and thus it's index value is at the ending value.
You can fix that with a closure that will freeze the loop value separately for each call to addThisThingtoList() like this:
for (var j = 0 ; j < 30 ; j += 1) {
(function(index) {
addThisThingtoList(function () {
console.log( "item" + index);
});
})(j);
}
Working demo: http://jsfiddle.net/jfriend00/A5cJG/
By way of explanation, this is an IIFE (immediately invoked function expression). The variable j is passed to the IIFE and it becomes a named argument to the function that I named index. Then, inside that function, you can refer to index as the value of j that is frozen uniquely and separately for each call to addThisThingtoList(). I could have named the argument index to also be j in which case it would have just overriden the higher scoped j, but I prefer to use a separate variable name to be more clear about what is what.
Here's a good reference on the IIFE concept if you want to read more about it:
http://benalman.com/news/2010/11/immediately-invoked-function-expression/
This is what closure is all about.
When you call the function, it pulls the value of j at the time it's called, not at the time when it was added to the list.
So by the time you start calling the functions, j is already at 30.
It's a classic javascript scope bug. You need to pass in the j variable to your function:
addThisThingToList(function(j) {
console.log("item" + j);
});
As #Smeegs says, "this is what closure is all about."

Categories

Resources