3

If reverse == true I want to run one kind of loop, else I want to run another one.

Currently, here is an example of my code:

if (reverse) {
    for (var i = 0; i < length; i++) {
        ...
    }
} else {
    for (var i = length; i >= 0; i--) {
        ...
    }
}

The code inside is really big, and is quite the same. I could use a function, but this function would have so many params that is not a good choice.

So I've tried to do something like that:

var loopStart1 = startPageIndex;
if (!reverse) {
    condition1 = function(i) {
         return i < length;
    }
    increment1 = function(i) {
         return ++i;
    }
} else {
    condition1 = function(i) {
        return i >= 0;
    }
    increment1 = function(i) {
        return i--;
    }
}
mainLoop: for (var i = loopStart1; condition1(i); increment1(i)) {

But now I have an infinite loop.

Any idea on how to solve this issue?

5
  • whose length are we talking about? why not reversing the array? Commented Aug 3, 2018 at 11:27
  • It's a length of a page array. I guess can't really reverse it, the array is huge it would be really expensive Commented Aug 3, 2018 at 11:29
  • If you put the function right before the loops you dont need params Commented Aug 3, 2018 at 11:30
  • I guess you have the if condition block reversed. From what i can infer from the 2 code snippets it looks reversed.try to exchange the if condition block with else block. Commented Aug 3, 2018 at 11:34
  • You just need --i, and your code should work. Commented Aug 3, 2018 at 11:55

6 Answers 6

4

Why not do it inline?! ;)

var start = startPageIndex;
for (var i = start; (reverse && i >= 0) || (!reverse && i < length); reverse ? --i : ++i) { }
Sign up to request clarification or add additional context in comments.

1 Comment

Oh god my eyes.
3

Assuming the specific case is to traverse through an array either backwards or forwards, there are two simple ways to do that.

1) Just conditionally reverse the array before looping, or

2) Use a single loop but conditionally map the loop variable to something else. Something like...

for (var i = 0; i < length; i++) {
    var j = i;
    if (reverse) {
        j = length - (i + 1);
    }

    // ...then use j instead of i
}

Comments

1

If you want to make it dynamic, I wouldn't use a for loop, but a do..while loop to be easier to customize.

Your main function would just have a simple reverse bool flag and you could just pass that.

Inside that function that you want to depend on the reverse flag, you can use the ternary expression in the condition (x ? y : z)

Makes it clearer to read. In theory you can do it in a for loop directly, using two ternary directions.

do {

    //Your actions here, using i as counter

    //Here you will do the counter direction change
    if(reverse)
      i--;
    else
      i++;

  // Use ternary expression if (x ? y : z) in the while condition
  // Reads as: If x is true, do y, else do z
  // All in one line
} while(reverse ? i>=0 : i<n);

Ideally, in these situations I would consider using iterators.

2 Comments

Thank you for your answer, I didn't know we could use ternaries like that
You're welcome, they are fun but I prefer not using them since the readability suffers
0

How about a simple loop function,

Below I've created a simple function called myLoop, were you can pass the length, if it's reversed, and what callback you want for each loop iteration.

eg.

function myLoop(length, reverse, each) {
  var index;
  if (!reverse) {
    for (index = 0; index < length; index ++) each(index);
  } else {
    for (index = length -1; index >= 0; index --) each(index);
  }
}


function show(index) {
  console.log("Loop index = " + index);
}

console.log("forward");
myLoop(5, false, show);  //normal
console.log("revere");
myLoop(5, true, show);   //reversed

Comments

0

I would opt for the same code, just change the array.

var array = ['one', 'two', 'three'];
var reversed = true;

let arrToUse = reversed ? array.reverse() : array;

for (var i = 0; i < arrToUse.length; i++) {
  console.log(arrToUse[i]);
}

2 Comments

Not sure who downvoted but the "speed performance" is not affected as much so, for most cases, this should be the preferred approach .
Not sure either, mine's got down-voted twice. :) Be nice if people gave a reason, this would surely improve SO, anyway, I'll up-vote yours just because the person who down-voted hasn't given a reason.
0

Check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions

Primitive parameters (such as a number) are passed to functions by value; the value is passed to the function, but if the function changes the value of the parameter, this change is not reflected globally or in the calling function.

This is what happens when you call increment1(i), outer i in for loop is not changed. To fix it just set i from increment1(i)'s return value.

mainLoop: for (var i = loopStart1; condition1(i); i = increment1(i)) {

1 Comment

While this code may answer the question, it would be better to include some context, explaining how it works and when to use it. Code-only answers are not useful in the long run.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.