Loop doesn't stop when flag is set? - javascript

I am developing a program in which I need to stop a loop when a flag is true. This is a short example of that I want:
var aux = true;
for(i=0; i < limit && aux; i++)
{
...
if (condition)
aux = false;
}
When the condition should end the loop. But this is not true. What is the problem?
EDIT:
The code is as follows:
aux = true;
for(j=posX+1; j <= limitXTop && aux; j++)
if(j != limiteXSuperior)
{
if(map.getXY(j,posY)[0] == 2)
{
aux = false;
}
else
// Change
...
}
...
I print a message to check if the execution enter in the IF and it enter.

Instead of using the condition on the for, use only a break statement.
for(i=0; i < limit; i++)
{
...
if (condition)
break;
}

Let me guess ... i was not defined ?

Related

Is there anyway to make this code faster?

I have a code here that automatically tick a box when all three boxes are true, however this is taking forever to load as I have thousands of boxes in the sheet, is there any way to make this code quicker?
at the moment the code is making everything lag and unresponsive
function checkBox(j,k,l,m,result){
var result = true;
if ( j === true && k === true & l === true && m === true) {
result = true;
} else {
result = false;
}
return result;
}
if the first four boxes are tick, then box number 6 will automatically tick, but it's taking forever to load
Not sure what you are doing wrong, but this code took 46ms for 10,000 lines - a little longer to render on the screen.
function go(){
//set up a test table with every 10th row with all boxes ticked
let str="<table>";
for (let i=0;i<10000;i++){
str +="<tr>";
for (let j=0;j<4;j++){
str +="<td><input type='checkbox'></td>";
}
str +="<td> </td><td><input type='checkbox'</td>";
str +="</tr>";
}
str +="</table>";
container.innerHTML=str;
//start here to compute the result column
let start=(new Date()).getTime();
let table=container.querySelector("table");
let rows=table.querySelectorAll("tr");
for (let i=0;i<rows.length;i++){
let inputs=rows[i].querySelectorAll("input");
if(i%10==0){
for (let j=0;j<4;j++)inputs[j].checked=true;
}
else {
for (let j = 0; j < 4; j++) {
if (Math.random() < 0.5) inputs[j].checked = true;
}
}
inputs[4].checked=inputs[0].checked && inputs[1].checked && inputs[2].checked && inputs[3].checked;
}
alert((new Date()).getTime()-start);
}

How to use continue in a loop to change a value

I am trying to have a loop that gives me values from 1 to 30. However every number divisible by 10 I want to hard code the value to the corresponding word. Example would be value 10 = "Ten", 20 = "Twenty" and so on.
I tried to do this with 'continue', however my displayed results do not go pass "Ten".
for (i = 0; i <= 30; i++) {
if (i == 10) {
i = "Ten";
continue;
} if (i == 20) {
i = "Twenty";
continue;
}
console.log(i);
}
Results
Am I going on about it the right way? Could you please offer some hints so I can figure this out. Thank you,
I tried this initially. But didn't work.
for (i = 0; i <= 30; i++) {
if (i == 10) {
i = "Ten";
} if (i == 20) {
i = "Twenty";
}
console.log(i);
}
Just get rid of the continue statements. They cause the loop to immediately skip to the end and start another iteration. Thus, your console output statement is skipped. Also, you don't want to touch the loop variable, and it wouldn't hurt to have an else. Something like this:
var result;
for (i = 0; i <= 30; i++) {
if (i == 10) {
result = "Ten";
} else if (i == 20) {
result = "Twenty";
} else {
result = i;
}
console.log(result);
}
Or you could just log the desired output directly in each branch of the if/else chain:
for (i = 0; i <= 30; i++) {
if (i == 10) {
console.log("Ten");
} else if (i == 20) {
console.log("Twenty");
} else {
console.log(i);
}
}
I dont think you can change i and expect it to work as usual. hence as soon as you change the value to "TEN", the loop terminates..!!!!
When the counter i gets to ten, you are replacing it with a string, so when the control flow reaches the i++ part, your loop fails. What you should do is assign the value to be printed to another variable that is only used inside the body of the loop.

javascript determine which OR statement triggered if statement

I have a condition like this (this is much simplified, they are actually events):
if(!a || !b || !c || !d){
//do something with 1,b,c, or d
}
how do I determine which var triggered the if? Doing if(a) else if(b) is not really a good option here as it will result in a lot of repeated code.
You can just try with a function that returns the index of the first true condition, or -1 if all conditions are false:
var conditions = [];
conditions.push(a);
conditions.push(b);
conditions.push(c);
conditions.push(d);
// ...
var triggerer = (function(){
for(var i = 0; i < conditions.length; i++){
if(conditions[i]){ return i; };
}
return -1;
})();
if(triggerer != -1){
// Do something with conditions[triggerer]
}else{
// Do something when everything is false
}
Store your conditions in an array and check them in a loop:
var values = [a, b, c, d];
for(var i = 0; i < values.length; i++) {
if(!values[i]) {
//...
// `values[i]` is the *first* condition that satisfies the `if` statement.
break;
}
}

How to set an empty array in a for loop in JavaScript in case the array to loop is undefined?

I want to loop over an array called children which may or may not be defined.
Currently I'm doing this:
var i;
var foo = {/*"children": ["1","2","3","4"]*/};
for (i = 0; i < [foo.children || []][0]. length; i += 1) {
console.log("hello")
}
This works correctly, because in case children is undefined, [foo.children || []][0] ends up being [[]] whose first element is an empty array [].
Question:
Is there any way to leave away the outer array?
I don't want to use an if-clause testing for children, just modify the array.
One way would be:
for (i = 0; i < foo.children.length || [].length; i += 1) {
console.log("hello")
}
but I'm looking for other alternatives if exist.
Thanks
EDIT:
Here is a jsperf on all variants. Interesting...
var len = foo.children ? foo.children.length : 0;
for (i = 0; i < len; i++) {
...
}
Use parenthesis instead of that one-item-array:
for (i = 0; i < (foo.children || []).length; i += 1) {
or move it further outside:
for (i = 0; foo.children && i < foo.children.length; i += 1) {
which is very near to
if (foo.children) for (i = 0; i < foo.children.length; i += 1) {
which would indeed be the cleanest way. There's nothing wrong with an if-statement.
EDIT: According to comments on other answers the OP wants terse, but jsLint appropriate code. Here it is:
var i, c, foo = {}, console;
for (i = 0, c = foo.children; i < (c && c.length); i += 1) {
console.log("hello");
}
I will leave the other possibilitis here for people who don't have as strict requirements as the OP does.
You can use the && operator:
for (i = 0; i < (foo && foo.children && foo.children.length); i += 1) {
console.log("hello")
}
If there is a chance that foo is not defined at all, then you need something slightly worse:
for (i = 0; i < ((typeof foo === 'object') && foo.children && foo.children.length); i += 1) {
console.log("hello")
}
Or if you're sure that foo is an object, you can skip the first check:
for (i = 0; i < (foo.children && foo.children.length); i += 1) {
console.log("hello")
}
Another possible way:
for (i = 0; foo.children && i < foo.children.length; i += 1)
You could add a condition checking the existence of the array to your for loop like this:
for (i = 0; (typeof foo.children != 'undefined') && (i < foo.children.length); i++) {
// do something
}
/edit:
OK, others were a bit faster than me, and foo.children is a nice alternative to typeof foo.children != 'undefined' ;)
Why not using a function to hide all these dirty statements?
function each(array, fn) {
if (array) {
var i = -1;
while (++i < array.length) {
if (fn(array[i]) === false) return;
}
}
}

How to break nested loops in JavaScript? [duplicate]

This question already has answers here:
What's the best way to break from nested loops in JavaScript? [closed]
(18 answers)
Closed 3 years ago.
I tried this:
for(i = 0; i < 5; i++){
for(j = i + 1; j < 5; j++){
break(2);
}
alert(1);
}
only to get:
SyntaxError: missing ; before statement
So, how would I break a nested loop in JavaScript?
You should be able to break to a label, like so:
function foo () {
dance:
for (var k = 0; k < 4; k++) {
for (var m = 0; m < 4; m++) {
if (m == 2) {
break dance;
}
}
}
}
You need to name your outer loop and break that loop, rather than your inner loop - like this.
outer_loop:
for(i=0;i<5;i++) {
for(j=i+1;j<5;j++) {
break outer_loop;
}
alert(1);
}
There are at least five different ways to break out of two or more loops:
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
fast:
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
if (j === 2)
break fast;
}
}
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();
See Aaron's. Otherwise:
j=5;i=5 instead of break.
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
}
}
}
code copied from Best way to break from nested loops in Javascript?
Please search before posting a question. The link was the FIRST related question I saw on the left side of this page!
Unfortunately you'll have to set a flag or use labels (think old school goto statements)
var breakout = false;
for(i=0;i<5;i++)
{
for(j=i+1;j<5;j++)
{
breakout = true;
break;
}
if (breakout) break;
alert(1)
};
The label approach looks like:
end_loops:
for(i=0;i<5;i++)
{
for(j=i+1;j<5;j++)
{
break end_loops;
}
alert(1)
};
edit: label incorrectly placed.
also see:
http://www.devguru.com/Technologies/ecmascript/quickref/break.html
http://www.daaq.net/old/javascript/index.php?page=js+exiting+loops&parent=js+statements
In my opinion, it's important to keep your construct vocabulary to a minimum. If I can do away with breaks and continues easily, I do so.
function foo ()
{
var found = false;
for(var k = 0; (k < 4 && !found); k++){
for(var m = 0; (m < 4 && !found); m++){
if( m === 2){
found = true;
}
}
}
return found;
}
Be warned, after the loop, m and k are one larger that you might think. This is because m++ and k++ are executed before their loop conditions. However, it's still better than 'dirty' breaks.
EDIT: long comment #Dennis...
I wasn't being 100% serious about being 'dirty', but I still think that 'break' contravenes my own conception of clean code. The thought of having multi-level breaks actually makes me feel like taking a shower.
I find justifying what I mean about a feeling about code because I have coded all life. The best why I can think of it is is a combination of manners and grammar. Breaks just aren't polite. Multi level breaks are just plain rude.
When looking at a for statement, a reader knows exactly where to look. Everything you need to know about the rules of engagement are in the contract, in between the parenthesis. As a reader, breaks insult me, it feels like I've been cheated upon.
Clarity is much more respectful than cheating.
Use function for multilevel loops - this is good way:
function find_dup () {
for (;;) {
for(;;) {
if (done) return;
}
}
}
Wrap in a self executing function and return
(function(){
for(i=0;i<5;i++){
for (j=0;j<3;j++){
//console.log(i+' '+j);
if (j == 2) return;
}
}
})()
You return to "break" you nested for loop.
function foo ()
{
//dance:
for(var k = 0; k < 4; k++){
for(var m = 0; m < 4; m++){
if(m == 2){
//break dance;
return;
}
}
}
}
foo();
break doesn't take parameters. There are two workarounds:
Wrap them in a function and call return
Set a flag in the inner loop and break again right after the loop if the flag is set.
Break 1st loop:
for(i=0;i<5;i++)
{
for(j=i+1;j<5;j++)
{
//do something
break;
}
alert(1);
};
Break both loops:
for(i=0;i<5;i++)
{
var breakagain = false;
for(j=i+1;j<5;j++)
{
//do something
breakagain = true;
break;
}
alert(1);
if(breakagain)
break;
};
You can break nested for loops with the word 'break', it works without any labels.
In your case you need to have a condition which is sufficient to break a loop.
Here's an example:
var arr = [[1,3], [5,6], [9,10]];
for (var a = 0; a<arr.length; a++ ){
for (var i=0; i<arr[a].length; i++) {
console.log('I am a nested loop and i = ' + i);
if (i==0) { break; }
}
console.log('first loop continues');
}
It logs the following:
> I am a nested loop and i = 0
> first loop continues
> I am a nested loop and i = 0
> first loop continues
> I am a nested loop and i = 0
> first loop continues
The return; statement does not work in this case.
Working pen
function myFunction(){
for(var i = 0;i < n;i++){
for(var m = 0;m < n;m++){
if(/*break condition*/){
goto out;
}
}
}
out:
//your out of the loop;
}

Categories

Resources