【问题标题】:How to reverse the order in a FOR loop如何在 FOR 循环中反转顺序
【发布时间】:2011-04-04 22:02:38
【问题描述】:

我有一个像这样的简单 FOR 语句:

var num = 10,
    reverse = false;

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

reverse 为假时,我希望它返回 [0,1,2,3,4,5,6,7,8,9] 之类的内容

但是,当 reverse 为真时,它应该返回 [9,8,7,6,5,4,3,2,1,0]

什么是获得这个结果的最有效方法,而不是每次都检查循环内的 reverse 是真还是假?

我不想这样做:

var num = 10,
    reverse = false;

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

我只想在循环外检查一次reverse

【问题讨论】:

  • 你到底想做什么?因为如果它是创建一个数组,或者在一个数组上循环,总会有javascript函数 reverse w3schools.com/jsref/jsref_reverse.asp 你可以调用
  • w3schools 不太好。查看w3fools

标签: javascript performance for-loop


【解决方案1】:
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 ); }

编辑:

如下面的 cmets 所述,如果 i 未在其他地方声明并且您不打算将其设为全局变量,则使用您声明的其他变量声明它。

如果你不想修改num的值,那么先把它赋值给i

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

【讨论】:

  • 不错。我本来打算建议for(i = num; i--;) log(i);,但the consensus 似乎是你的方法最快。
  • 致操作员:请注意,num 在反向打印时会被修改,因此如果您打算将来使用该值,请务必复制原始值。跨度>
  • @Daniel - 非常正确。如果这是一个问题,这里是 else 声明的快速替换:else{i=num;while(i--)log(i)};
  • 别忘了在某处声明var i
  • @cobbal - OP 没有在问题中声明它,所以我认为它是在其他地方声明的,或者打算是全局的。如果不是,那么可以,它可以添加到 OP 的其他声明中。 var num = 10, reverse = false, i;
【解决方案2】:

尝试使用 2 个循环:

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

【讨论】:

  • 我正要发布几乎与此相同的内容。在我看来,这似乎是最自然、最易读的解决方案,而且效率也很高,反向标志只测试一次,而不是每次循环测试。
【解决方案3】:
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);
}

这等价于以下,可读性更强,但不太紧凑:

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

编辑:
实际上,这两种解决方案并不完全相同,因为第一种解决方案有一个额外的增量操作。尽管如此,从性能的角度来看,它仍然可以忽略不计。如果您真的想获得性能最佳的紧凑型解决方案,您可以执行以下操作(不适合胆小的人):

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

这具有单一控制结构、每个循环中的单一测试和单一迭代器添加的优点。它没有迭代器递增/递减那么快,但也只有一点点。

【讨论】:

  • 哈哈。你写你的就像我写我的一样(发布新答案时页面刷新)。 :P 我滥用三元语句。很高兴看到有人像我一样写作。
  • 那里没有滥用三元...我认为只有当您不使用三元表达式的返回值时才会滥用条件? doSomething() : doSomethingElse(); --- 完全不在话下,不过......
  • 我喜欢你的解决方案,但我发现 patrick 的解决方案更清楚。
【解决方案4】:
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&lt;=end 将在此处出现问题,因为检查需要反向为 i&gt;=0
  • 第一个子句应该是end=-1,第二个子句应该是end=num
【解决方案5】:

前几天我刚发现需要这个。我是这样做的:

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

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

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

无需单独的循环,也无需进行数学运算来计算循环中正确的i

所以如果reversetrue...

  • i(代表我们的第一项)变为num - 1,所以我们现在开始处理本应是最后一项的内容

  • num(表示越界)变为-1,所以我们现在停止处理本应是第一项的内容

  • direction-1,这意味着当我们做i += direction时它会递减

因此,通过将起点与终点交换并将i 的更改从1 更改为-1,我们将根据这些修改上升或下降。

【讨论】:

    【解决方案6】:

    我认为这符合您的要求:

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

    【讨论】:

      【解决方案7】:

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

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

      【讨论】:

        【解决方案8】:

        你有什么问题:

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

        }

        【讨论】:

        • 也许在生产代码中,循环内部会发生比简单的console.log更多的事情?
        • @meagar:如果是这样,请将循环内的所有内容推入一个函数中。
        【解决方案9】:

        Roy 的和我的很相似,但这是我的想法。我会给你我用 C# 写的东西,以及我认为它是如何翻译成 Javascript 的。

        C#

            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();
        

        Javascript

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

        还有一种方法
        Javascript

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

        【讨论】:

        • 所有这些仍然在循环的每次迭代中测试反向标志。
        • 哈哈。我的错,我没有看到问题中的那部分。谢谢你让我知道。但是,对于 OP,如果您担心性能,我不会。如果可以的话,我会想点别的。
        • 我认为 OP 不知道三元语句,认为他们的循环中必须有一个 if/else。不过,我仍在考虑另一种方式。
        【解决方案10】:

        它似乎有效:

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

        【讨论】:

          【解决方案11】:

          在像 Javascript 这样的语言中,肯定有一种方法可以定义一个本地函数并在循环中使用它吗?

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

          虽然不懂 Javascript,但我不知道函数定义的实际形式。

          【讨论】:

            【解决方案12】:
            //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)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2020-05-06
              • 2015-12-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-05-06
              • 1970-01-01
              • 2021-02-06
              相关资源
              最近更新 更多