如何在 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<=end
将在此处出现问题,因为检查需要反向为 i>=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
。
所以如果reverse
是true
...
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 循环中反转顺序的主要内容,如果未能解决你的问题,请参考以下文章