简体   繁体   中英

How to reverse the order in a FOR loop

I've a simple FOR statement like this:

var num = 10,
    reverse = false;

for(i=0;i<num;i++){
    console.log(i);
}

when reverse is false I want it to return something like [0,1,2,3,4,5,6,7,8,9]

but, when reverse is true, it should return [9,8,7,6,5,4,3,2,1,0]

Which is the most efficient way to get this result, without checking every time if reverse is true or false inside the loop?

I don't want to do this:

var num = 10,
    reverse = false;

for(i=0;i<num;i++){
    if(reverse) console.log(num-i)
    else console.log(i)
}

I would like to check reverse only one time outside the loop.

var num = 10,
reverse = false;

if(!reverse) for( var i=0;i<num;i++) log(i);
else         while(num-- )      log(num);

   // to avoid duplication if the code gets long
function log( num ) { console.log( num ); }

EDIT:

As noted in the comments below, if i is not declared elsewhere and you do not intend for it to be global, then declare it with the other variables you declared.

And if you don't want to modify the value of num , then assign it to i first.

var num = 10,
reverse = false,
i;

if(!reverse) for(var i=0;i<num;i++) log(i);   // Count up
else         {var i=num; while(i--) log(i);}  // Count down

function log( num ) { console.log( num ); }

Try use 2 loops:

if (reverse) {
    for(i=num-1;i>=0;i--){
        console.log(i)
    }
}
else {
    for(i=0;i<num;i++){
        console.log(i)
    }
}
var num = 10,
    reverse = false;

for (var i = 0, n = reverse?num-1:0, d = reverse?-1:1; i < num; i++, n+=d) {
    console.log(n);
}

This is equivalent to the following, which is more readable, but less compact:

var num = 10,
    reverse = false;

var start = reverse ? num-1 : 0,
    end   = reverse ? -1 : num,
    step  = reverse ? -1 : 1;
for (var i = start; i != end; i += step) {
    console.log(i);
}

Edit:
Actually, these two solutions are not identical, because the first one has an additional increment operation. Still, it is negligible from performance point of view. If you really want to get a compact solution that has the best performance, you can do the following (not for the faint of heart):

var num = 10,
    reverse = false;

for (var r=reverse, i=r?num-1:0, n=r?-1:num, d=r?-1:1; i!=n; i+=d) {
    console.log(i);
}

This has the advantage of having a single control structure, a single test in each loop, and a single iterator addition. It is not as fast as having an iterator increment/decrement, but only marginally so.

var start; var end; var inc;
if (reverse) {
    start = num-1; end = 0; inc = -1;
}
else {
    start = 0; end = num-1; inc = 1;
}
for(i=start;i!=end;i+=inc){
    console.log(i)
}

I just came across the need for this the other day. Here's how I did it:

var num = 10,
    i = 0,
    direction = 1, 
    reverse = false;

if(reverse)
    i = num + (direction = num = -1);

for(; i !== num; i += direction) {
    console.log(i);
}

No need for separate loops, and no need to do math to calculate the proper i in the loop.

So if reverse is true ...

  • i (which represents our first item) becomes num - 1 , so we're now starting on what would have been the last item

  • num (which represents out of bounds) becomes -1 , so we're now stopping on what would have been the first item

  • direction is -1 , which means it will decrement when we do i += direction

So by swapping our starting point with our ending point and changing the alteration of i from 1 to -1 , we'll be going up or down based on those modifications.

I think this meets your requirements:

var num = 10;
var reverse = false;
var diff = 0;

if (reverse) {
    diff = num - 1;
}

for (i = 0; i < num; i++) {
    console.log(Math.abs(diff - i));
}

这是我一直以来做反向循环的方式:

for (i = num; --i >= 0; ) ...

And what's your problem with:

   if (reverse)
   {
     for(i=num-1; i>=0;i--){ 
          console.log(i);
      }
   }
   else
   {
      for(i=0;i<num;i++){ 
         console.log(i) 
      } 
   }

}

Roy's is similar to mine, but here's what I was thinking. I'll give you what I wrote in C# and how I think it translates to Javascript.

    int num = 10;
    bool reverse = true;

    for (int i = reverse ? num : 0; (reverse ? 0 : i) < (reverse ? i : num); i += reverse ? -1 : 1)
    {
        Console.Write((reverse ? i - 1 : i).ToString());
    }
    Console.ReadKey();

        var num = 10,
        reverse = true;

    for (int i = reverse ? num : 0; (reverse ? 0 : i) < (reverse ? i : num); i += reverse ? -1 : 1)
    {
        console.log(reverse ? i - 1 : i);
    }


    var num = 10,
        reverse = false;

    for (int i = 0; i < num; i++)
    {
      console.log((reverse ? abs(-num + (i + 1)) : i));

    }

It seems to work:

  var num = 10;
  var z = 1;
  var k = -10;
  if (reverse ){
    k = -1;
    z = -1;
  }
  for(int i = 0; i < 10; i++){
    console.log(num+i*z+k);
  }

Surely in a language like Javascript there must be a way to define a local function and use that in the loop?

function SubtractFrom(val, subtractor) {
    return val - subtractor;
}

function PassThrough(val) {
    return val;
}

var num = 10;
var processor = reverse ? SubtractFrom(num-1) : PassThrough;

for (i = 0; i < num; i++) {
    console.log(processor(i));
}

Not knowing Javascript though, I don't know what actual form the function definitions would take.

//reverse a number
let c = [2,3,5,67,4]
let sum = '';
let d = c.toString().split('')
console.log(d)
for(let i = d.length-1; i >= 0; i--) {
    sum += d[i]
}
console.log(sum)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM