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