Why does my if and else statement print at the same time? - javascript

Why does the else and if statement print? Checking if arrays have matching
elements on line 5 which they do...so just my if statement should print.
However my alert condition prints with the if condition.I've tried rearranging code,still no luck.
var array1 = [1, 89, 3, 4, 5];
var array2 = [1, 2, 7, 10, 89];
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 6; j++) {
if (array1[i] == array2[j]) {
document.getElementById("demo").innerHTML =
"Hello World" //Should just print this since elements match
break;
} else {
alert("Error");
break;
}
}
}

If you want to stop the outer loop when you find a match in the inner loop, you need to give a label parameter to break.
outer:
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 6; j++) {
if (array1[i] == array2[j]) {
document.getElementById("demo").innerHTML =
"Hello World" //Should just print this since elements match
break outer;
} else {
alert("Error");
break;
}
}
}
You still may get some alerts before Hello World is displayed. Your code alerts for every non-matching pair of elements until it finds a match. So unless the matching elements are first in both arrays, you'll get a bunch of alerts before it displays Hello world.
Also, since you have break in both the if and else blocks, you'll never get past the first iteration of the j loop.
If you just want a single alert that indicates that no matching elements were found, you need to move it out of the loop.
var match_found = false;
outer:
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 6; j++) {
if (array1[i] == array2[j]) {
document.getElementById("demo").innerHTML =
"Hello World" //Should just print this since elements match
match_found = true;
break outer;
}
}
}
if (!match_found) {
alert("Error");
}

a for loop will repeat very quickly, which is why you can not see the them doing it at diffrent times;
your code does not output at the same time, it is just to fast.
if you are looking into delay, take a look at setInterval.

Just skip the else part. You don't really need that. Unless you wish to do something else if the condition is not true, omit the else statement.

When you call break it only terminates the inner loop. The outer loop will continue to iterate, your conditions will be checked again, and then the else statements run instead.
An alternative way to do this would be:
(function() {
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 6; j++) {
if (array1[i] == array2[j]) {
document.getElementById("demo").innerHTML =
"Hello World" //Should just print this since elements match
return;
} else {
alert("Error");
return;
}
}
}
})();
Wrapping the code in a self executing function allows you to replace break with return to exit the entire function.

Related

Conditional Pop-up Box within a for loop (Sheets)

I got the code below working, but when I try to add a Browser.msgBox() once there is a duplicate in the comparison, the code keeps running until it exceeds its time limit.
The idea is to notify the user that the item he/she is trying to add is duplicated and have the script stop running.
var duplicate = false;
for(var x = 0; x < data.length; x++) {
for(var j = 0; j < dataArquivoItens.length; j++){
if(data[x].join() == dataArquivoItens[j].join()){
duplicate = true;
break;
}
}
}
Thanks a lot!
You are only breaking out from the if statement, this is why your code keeps iterating
If you want to break from all nested loops/ statements - give them a name
Sample:
var duplicate = false;
loop1:
for(var x = 0; x < data.length; x++) {
loop2:
for(var j = 0; j < dataArquivoItens.length; j++){
if(data[x].join() == dataArquivoItens[j].join()){
duplicate = true;
Browser.msgBox("That's a duplicate");
break loop1;
}
}
}

Why does this program print 3 and not 2?

I am currently learning JavaScript, and right now I am on a topic discussing the differences between let and var.
Can someone explain why this code prints 3 and not 2? How does i even reach the value of 3 when the loop should stop executing once i becomes 2?
var i;
function printNumTwo() {
return i;
}
for (i = 0; i < 3; i++) {
if(i === 2) {
printNumTwo();
}
}
print(printNumTwo()); // prints 3
You are not printing anything while i is 2, only after the loop is when you call print. The Loop stops when i becomes 3.
To have it print 2, you have to change the printNumTwo() function like so:
var i;
function printNumTwo() {
print(i);
}
for (i = 0; i < 3; i++) {
if(i === 2) {
printNumTwo();
}
}
it because you have this line
for (i = 0; i < 3; i++) {
which increment value of i, and i is global variable and when you call you printNumTwo i value reached to 3 because of loop increment i value
When you print(printNumTwo()) i is 3. Calling printNumTwo() in the if statement does nothing but returning i which is not used by anything.
So basically the for statement runs and finishes making i=3 and then i is used by your print method.
You have to change start loop with let keyword because var is a global variable and let is block scope variable. that's why getting the different value.
You can try this
var i;
function printNumTwo() {
return i;
}
for (let j = 0; j < 3; j++) {
i = j;
if(i === 2) {
printNumTwo();
}
}
cosole.log(printNumTwo());
Try to use break statement it "jumps out" of a loop and continues executing the code after the loop if the specified condition is true.
var i;
function printNumTwo() {
return i;
}
for (i = 0; i < 3; i++) {
if (i === 2) {
break;
printNumTwo();
}
}
document.write(printNumTwo()); // prints 2

JavaScript, brackets on for loop causing errors?

I have a function that takes an input of a string and a single char that will count how many times that char appears in that string.
function count(str, letter) {
var num = 0;
for (var i = 0; i < str.length; i++)
if (str.charAt(i) == letter)
num += 1;
return num;
}
console.log(count("BBC", "B"));
//output 2
It works fine like this, but this took me some time to figure out. Its second hand nature for me to always put brackets on a for loop but when i do that, the function doesn't work as i anticipated it would, like so:
function count(str, letter) {
var num = 0;
for (var i = 0; i < str.length; i++) {
if (str.charAt(i) == letter)
num += 1;
return num;
}
}
console.log(count("BBC", "B"));
//outputs 1
Why are the brackets causing it to act this way?
Why are the brackets causing it to act this way?
Because you have the return statement inside of the for loop block. At the end of the block, the function returns.
function count(str, letter) {
var num = 0;
for (var i = 0; i < str.length; i++) { // block start
if (str.charAt(i) == letter)
num += 1;
return num; // exit function in first loop
} // block end
}
It's not the braces (brackets are []), it's the placement of the return statement. The return statement is in the first iteration of the loop (i = 0). If you add an extra set of braces (as seen below), it becomes more obvious.
function count(str, letter) {
var num = 0;
for (var i = 0; i < str.length; i++) {
if (str.charAt(i) == letter) {
num += 1;
}
return num; // <-- This return exits the function
}
}
console.log(count("BBC", "B"));
//outputs 1
In the First one return statement was outside for loop, but in the second one return statement is inside the for loop. That made the difference.
Try the below code.
function count(str, letter) {
var num = 0;
for (var i = 0; i < str.length; i++) {
if (str.charAt(i) == letter)
num += 1;
}
return num;
}
console.log(count("BBC", "B"));
your loop gets terminated after first iteration.
So if you try to get the occurrence of "B" in "XBBBB...B" it will return 0.
Try to debug your code and place brackets at right position.
Learn to debug your js code using browser.

How to detect the end of the loop in javascript

Using for(var i = 0; i < str.length; i++) I can easily detect if the loop is at the end.
But I how can I know if I'm using for or for each.
for(var i = 0; i < str.length; i++) {
if(End of for) //Do something if the end of the loop
}
how to find the last loop in for in javascript ?
for(var i = 0; i < str.length; i++) {
if(i== str.length-1) {
//Do something if the end of the loop
}
}
using forin
for (var item in str) {
if(str[str.length-1] == item) {
//Do something if the end of the loop
}
}
const str = "I am a 24 letter string!";
for (let i = 0; i < str.length; i++) {
if (i + 1 === str.length) {
console.log('Last loop:', i + 1)
}
}
for (var item in str) {
if(str[parseInt(item)+1] === undefined) {
//Do something if the end of the loop
}
}
for(var i = 0; i < arr.length; i++){
if(i == (arr.length - 1)){
//do you stuff
}
}
Just separate the last thing from the loop. Note the use of str.length - 1 in the condition.
//from the beginning up to but not including the last index
for(var i = 0; i < str.length - 1; i++) {
console.log(i)
}
//from the last index only
console.log(str.length - 1)
In a forEach loop, you must iterate linearly over the array, so some conditional logic and a counter are necessary to detect the last element. I find the below harder to read and less efficient especially if you really use an anonymous function in that way. Moreover because of this need for a counter, it simply makes more sense to use the first approach I shared.
var i = 0;
array.forEach(function(i) {
if(i === str.length - 1) {
//do the last thing
} else {
//do all the other things
}
i++;
});
You could use console.log(). If you put this inside the loop, you will be able to view each result in the console.
console.log(i);

What's the best way to break from nested loops in JavaScript? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 months ago.
Improve this question
What's the best way to break from nested loops in Javascript?
//Write the links to the page.
for (var x = 0; x < Args.length; x++)
{
for (var Heading in Navigation.Headings)
{
for (var Item in Navigation.Headings[Heading])
{
if (Args[x] == Navigation.Headings[Heading][Item].Name)
{
document.write("<a href=\""
+ Navigation.Headings[Heading][Item].URL + "\">"
+ Navigation.Headings[Heading][Item].Name + "</a> : ");
break; // <---HERE, I need to break out of two loops.
}
}
}
}
Just like Perl,
loop1:
for (var i in set1) {
loop2:
for (var j in set2) {
loop3:
for (var k in set3) {
break loop2; // breaks out of loop3 and loop2
}
}
}
as defined in EMCA-262 section 12.12. [MDN Docs]
Unlike C, these labels can only be used for continue and break, as Javascript does not have goto.
Wrap that up in a function and then just return.
I'm a little late to the party but the following is a language-agnostic approach which doesn't use GOTO/labels or function wrapping:
for (var x = Set1.length; x > 0; x--)
{
for (var y = Set2.length; y > 0; y--)
{
for (var z = Set3.length; z > 0; z--)
{
z = y = -1; // terminates second loop
// z = y = x = -1; // terminate first loop
}
}
}
On the upside it flows naturally which should please the non-GOTO crowd. On the downside, the inner loop needs to complete the current iteration before terminating so it might not be applicable in some scenarios.
I realize this is a really old topic, but since my standard approach is not here yet, I thought I post it for the future googlers.
var a, b, abort = false;
for (a = 0; a < 10 && !abort; a++) {
for (b = 0; b < 10 && !abort; b++) {
if (condition) {
doSomeThing();
abort = true;
}
}
}
Quite simple:
var a = [1, 2, 3];
var b = [4, 5, 6];
var breakCheck1 = false;
for (var i in a) {
for (var j in b) {
breakCheck1 = true;
break;
}
if (breakCheck1) break;
}
Here are five ways to break out of nested loops in JavaScript:
1) Set parent(s) loop to the end
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
{
i = 5;
break;
}
}
}
2) Use label
exit_loops:
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
break exit_loops;
}
}
3) Use variable
var exit_loops = false;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
{
exit_loops = true;
break;
}
}
if (exit_loops)
break;
}
4) Use self executing function
(function()
{
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
return;
}
}
})();
5) Use regular function
function nested_loops()
{
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
return;
}
}
}
nested_loops();
var str = "";
for (var x = 0; x < 3; x++) {
(function() { // here's an anonymous function
for (var y = 0; y < 3; y++) {
for (var z = 0; z < 3; z++) {
// you have access to 'x' because of closures
str += "x=" + x + " y=" + y + " z=" + z + "<br />";
if (x == z && z == 2) {
return;
}
}
}
})(); // here, you execute your anonymous function
}
How's that? :)
How about using no breaks at all, no abort flags, and no extra condition checks. This version just blasts the loop variables (makes them Number.MAX_VALUE) when the condition is met and forces all the loops to terminate elegantly.
// No breaks needed
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
if (condition) {
console.log("condition met");
i = j = Number.MAX_VALUE; // Blast the loop variables
}
}
}
There was a similar-ish answer for decrementing-type nested loops, but this works for incrementing-type nested loops without needing to consider each loop's termination value for simple loops.
Another example:
// No breaks needed
for (var i = 0; i < 89; i++) {
for (var j = 0; j < 1002; j++) {
for (var k = 0; k < 16; k++) {
for (var l = 0; l < 2382; l++) {
if (condition) {
console.log("condition met");
i = j = k = l = Number.MAX_VALUE; // Blast the loop variables
}
}
}
}
}
If you use Coffeescript, there is a convenient "do" keyword that makes it easier to define and immediately execute an anonymous function:
do ->
for a in first_loop
for b in second_loop
if condition(...)
return
...so you can simply use "return" to get out of the loops.
I thought I'd show a functional-programming approach. You can break out of nested Array.prototype.some() and/or Array.prototype.every() functions, as in my solutions. An added benefit of this approach is that Object.keys() enumerates only an object's own enumerable properties, whereas "a for-in loop enumerates properties in the prototype chain as well".
Close to the OP's solution:
Args.forEach(function (arg) {
// This guard is not necessary,
// since writing an empty string to document would not change it.
if (!getAnchorTag(arg))
return;
document.write(getAnchorTag(arg));
});
function getAnchorTag (name) {
var res = '';
Object.keys(Navigation.Headings).some(function (Heading) {
return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
if (name == Navigation.Headings[Heading][Item].Name) {
res = ("<a href=\""
+ Navigation.Headings[Heading][Item].URL + "\">"
+ Navigation.Headings[Heading][Item].Name + "</a> : ");
return true;
}
});
});
return res;
}
Solution that reduces iterating over the Headings/Items:
var remainingArgs = Args.slice(0);
Object.keys(Navigation.Headings).some(function (Heading) {
return Object.keys(Navigation.Headings[Heading]).some(function (Item) {
var i = remainingArgs.indexOf(Navigation.Headings[Heading][Item].Name);
if (i === -1)
return;
document.write("<a href=\""
+ Navigation.Headings[Heading][Item].URL + "\">"
+ Navigation.Headings[Heading][Item].Name + "</a> : ");
remainingArgs.splice(i, 1);
if (remainingArgs.length === 0)
return true;
}
});
});
How about pushing loops to their end limits
for(var a=0; a<data_a.length; a++){
for(var b=0; b<data_b.length; b++){
for(var c=0; c<data_c.length; c++){
for(var d=0; d<data_d.length; d++){
a = data_a.length;
b = data_b.length;
c = data_b.length;
d = data_d.length;
}
}
}
}
Already mentioned previously by swilliams, but with an example below (Javascript):
// Function wrapping inner for loop
function CriteriaMatch(record, criteria) {
for (var k in criteria) {
if (!(k in record))
return false;
if (record[k] != criteria[k])
return false;
}
return true;
}
// Outer for loop implementing continue if inner for loop returns false
var result = [];
for (var i = 0; i < _table.length; i++) {
var r = _table[i];
if (!CriteriaMatch(r[i], criteria))
continue;
result.add(r);
}
There are many excellent solutions above.
IMO, if your break conditions are exceptions,
you can use try-catch:
try{
for (var i in set1) {
for (var j in set2) {
for (var k in set3) {
throw error;
}
}
}
}catch (error) {
}
Hmmm hi to the 10 years old party ?
Why not put some condition in your for ?
var condition = true
for (var i = 0 ; i < Args.length && condition ; i++) {
for (var j = 0 ; j < Args[i].length && condition ; j++) {
if (Args[i].obj[j] == "[condition]") {
condition = false
}
}
}
Like this you stop when you want
In my case, using Typescript, we can use some() which go through the array and stop when condition is met
So my code become like this :
Args.some((listObj) => {
return listObj.some((obj) => {
return !(obj == "[condition]")
})
})
Like this, the loop stopped right after the condition is met
Reminder : This code run in TypeScript
Assign the values which are in comparison condition
function test(){
for(var i=0;i<10;i++)
{
for(var j=0;j<10;j++)
{
if(somecondition)
{
//code to Break out of both loops here
i=10;
j=10;
}
}
}
//Continue from here
}
An example with for .. of, close to the example further up which checks for the abort condition:
test()
function test() {
var arr = [1, 2, 3,]
var abort = false;
for (var elem of arr) {
console.log(1, elem)
for (var elem2 of arr) {
if (elem2 == 2) abort = true;
if (!abort) {
console.log(2, elem2)
}
}
}
}
Condition 1 - outer loop - will always run
The top voted and accepted answer also works for this kind of for loop.
Result: the inner loop will run once as expected
1 1
2 1
1 2
1 3
XXX.Validation = function() {
var ok = false;
loop:
do {
for (...) {
while (...) {
if (...) {
break loop; // Exist the outermost do-while loop
}
if (...) {
continue; // skips current iteration in the while loop
}
}
}
if (...) {
break loop;
}
if (...) {
break loop;
}
if (...) {
break loop;
}
if (...) {
break loop;
}
ok = true;
break;
} while(true);
CleanupAndCallbackBeforeReturning(ok);
return ok;
};
the best way is -
1) Sort the both array which are used in first and second loop.
2) if item matched then break the inner loop and hold the index value.
3) when start next iteration start inner loop with hold index value.

Categories