如何在 FOR 循环中反转顺序

Posted

技术标签:

【中文标题】如何在 FOR 循环中反转顺序【英文标题】:How to reverse the order in a FOR loop 【发布时间】: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。 【参考方案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 声明的快速替换:elsei=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)

【讨论】:

以上是关于如何在 FOR 循环中反转顺序的主要内容,如果未能解决你的问题,请参考以下文章

csharp 如何使用for循环反转数组的示例。

csharp 如何使用for循环反转数组的示例。

如何使用循环反转numpy数组

如何以相反的顺序快速迭代for循环?

如何在一个循环执行ajax方法里面嵌套的ajax方法

为啥这个for循环不执行?