roperzh
roperzh

Reputation: 960

Incrementing a loop variable more than once per loop based on conditionals

Let's suppose that I have a for loop, and under certain condition I want to increment the value of my control variable (i) in order to skip the next element to be looped, for example:

for (var i = 0; i < arr.length; i++) { 
  if (someCondition) {
    // Call a function and increment i in order to skip the next item
    callFunction(arr[i], arr[++i]);
  } else {
    // Do something else
  }
}

While this works fine, I'm concerned about how good practice is to do something like that:

Thanks in advance.

Upvotes: 1

Views: 111

Answers (4)

skypjack
skypjack

Reputation: 50540

  • Is clear what is happening at first glance?

More or less. At a first glance, the reader could suppose that the loop runs length times, while actually it can runs half the times. Anyway, by looking at the code it's quite clear what's happening even to not experienced developers. The question had to be: is it easy to read? Not so much, at least to me.I'd rather use a pair object because it's easier to understand, but it has its drawbacks too (to create pairs means having more objects around, the need to derefer them and so on).

  • Is it a bad practice?

Not, it isn't. Usually vectors are allocated using contiguous memory, so as an example it's worth it to get the best from your CPU cache in some cases (to have a pair here may or not lead to derefer something, thus invalidating your efforts - try to think about how you would implement a pair in JavaScript). That's only an example, of course, but it should give the idea that the practices also depend on the intended goals. Even the goto towards almost everybody is banding words found its uses in the kernel, but have you ever heard someone call it a good practice?

  • Can I have an unexpected side effect?

Well, in such a case, the length of the array is not strictly checked once entered the if. Because of that and the way JavaScript works, you must be ready at least to see undefined values pushed around from within this loop. As someone said in a comment, such an approach is a good way to bury bugs in your code, for you are assuming that the caller has correctly built the array for you. Sooner or later, someone will do a mistake and you'll probably banish the one that wrote that code from you team.

Note

This comment is the worst part, indeed:

// Call a function and increment i in order to skip the next item

Here you are not simply trying to skip an element, instead you are passing it as an argument to the called function. If you are receiving also that function as an argument (as an example, that's a sort algorithm and the function is your less operator), this way you are introducing a risky invokation that could result in an exception thrown somewhere.

Not so good. :-)

Upvotes: 1

Iecya
Iecya

Reputation: 279

Why should you skip and element inside a loop?

Anyway I should use a specific variable to avoid i forced increment, which could give some problem.

I would write it this way:

var skip = false;
for (var i = 0; i < arr.length; i++) { 
    if(skip == false) {
        if (someCondition) {
        // change skip value
        skip = true;
      } else {
        // Do something else
      }
    }
    else {
        //reset skip value to false in order to go on with your loop and do nothing else
        skip = false;
    }

}

Upvotes: 0

juvian
juvian

Reputation: 16068

You could store a boolean indicating if it should skip the next item:

var skip = false;

for (var i = 0; i < arr.length; i++) {
    if (skip == true) {
        skip = false;
        continue;
    }
    if (someCondition) {
        skip = true;
        callFunction(arr[i], arr[i + 1]);
    } else {
        // Do something else
    }
}

Upvotes: 2

jahanzaib ali
jahanzaib ali

Reputation: 19

You can use even continue keyword to skip your required iteration except increasing the code and if statements

your code will looks like

for (var i = 0; i < arr.length; i++) { 
  if (someCondition)
    continue;
    callFunction(arr[i], arr[++i]);
}

Upvotes: 1

Related Questions