Chris Barrett
Chris Barrett

Reputation: 601

Break and Continues

I wonder if someone can clarify something for me. I have a bit of code to check an array for overlapping values depending on different values. Basically its the contents of a google sheet in rows and comumns for this is specifically GAS. What I have at the moment is

  var e = [[2,4,3,4,2],[1,5,3,6,2],[2,4,3,4,1],[1,4,3,6,1],[2,4,3,6,5]];
  var i; //id of entry to check
  var j; //id of element to check
  var k; //id of entry to compare

  for (i in e){ //2D ARRAY ARRAY
      for (k in e){ //ELEMENT TO COMPARE
           if (e[i][2] === e[k][2] && e[i][3] === e[k][3] && e[i][0] && e[i][0] >= e[k][0] && e[i][1] <= e[k][1] && e[i][4] <= e[k][4] &&  i !=k){
             e.splice(i,1);
             continue;
           }
      }
  }
  return e;

I had to add the continue; as otherwise if the last array checked was also marked for splice the code failed. But I assumed break would also work in place of continue but for some reason it does not. I thought break would return to the outside loop but does it permanently break that bit of code?

Thanks people

EDIT: spoke too soon. code still fails even with continue. head scratching continues

Upvotes: 2

Views: 83

Answers (2)

Jonas Wilms
Jonas Wilms

Reputation: 138267

continue jumps directly to the next iteration, so:

  while(true) {
    console.log("a");
    continue;
    console.log("b");
 }

will only log a as it will jump back to the beginnig of the loop if it reaches continue.If you however move continue to the last line of the loop (just as in your code) it does nothing as it would jump to the begining to the loop one line later, so it just skips an empty line.

I thought break would return to the outside loop

Yup, thats what happens and that is actually a good thing as if you removed the element already, it won't make sense to check for other dupes as you don't want to remove it twice.

Now the real problem is that splice changes the indexes, so if you splice out the fourth element, the fith element becomes the fourth element, but the loop continues to the fith element without checking the fourth element again (which is now a different one). Therefore you have to go back by one element before you break:

 for(let i = 0; i < e.length; i++) {
   for(let k = 0; k < e.length; k++) {
      if(i === k) continue; // < good usecase
      if(/* equality checks */) {
        e.splice(i, 1); // remove the element
        i--; // go back by one as we changed the order
        break; // exit the inner loop
     }
   }
 }

IMO:

1) I would favor for(const [i, value] of arr.entries() over for..in

2) you will forget what arr[i][2] is very soon, giving proper names to the indexes makes it way more readable:

  const [idA, someValueA] = e[i];
  const [idB, someValueB] = e[k];
  if(idA === idB && someValueA <= someValueB // ...

3) e is a bad name.

Upvotes: 3

QuentinUK
QuentinUK

Reputation: 3077

You can use a labelled break to break out of nested loops. eg

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++;
  }
}

Upvotes: 2

Related Questions