对于方向未知的两个数字之间的循环



我正在用C#编写一个图形程序,但我想不出在两个值之间运行for循环的好方法,其中一个值可能比另一个值大或小。

为了证明,当X2>X1:

for (int x = X1; x<=X2; x++) {
//code
}

然而,当X2<在这种情况下,我想发生的是,循环从X1开始,一直倒退到X2。

由于我正在执行图形程序,当X2<X1,因为这意味着交换它们相关的Y值,这可能仅对Y值产生相同的问题。循环必须始终从X1开始,需要更改的是方向(+/-),而不是值的顺序。

我想到了一些解决方案,但它们都有缺陷,值得注意的是X1永远不会等于X2。

#1:复制循环

if (X2<X1) {
for (int x = X1; x>=X2; x--) {/*code*/}
} else {
for (int x = X1; x<=X2; x++) {/*code*/}
}

由于复制代码而不适用,特别是如果"//code"部分特别长

#2:很多燕鸥

for (int x = X1; x!=X2+(X2<X1?-1:1); x+=(X2<X1?-1:1)) {/*code*/}

虽然这段代码很好用,很简洁,但可读性很差。此外,我在不同的地方看到,使用"不等于"作为循环约束是一种糟糕的做法来源

#3:使用while循环

int x = X1;
while(true) {
//code
if (X2<X1) {
x--;
if (x<X2) break;
} else {
x++;
if (x>X2) break;
}
}

这个解决方案似乎很长,很难执行这样一个简单的任务,此外,使用"while(true)"也是错误的做法来源

我认为最可读的选择是从重复代码中简单地创建/提取方法(第一个提出的版本):

void ComputeRenderedStuff(int x) 
{
// do your computations for x
}
if (X2<X1) 
for (int x = X1; x>=X2; x--) 
ComputeRenderedStuff(x);
else
for (int x = X1; x<=X2; x++)
ComputeRenderedStuff(x);

一个简单的解决方案是为循环本身使用一个变量,为步骤使用另一个变量:

int length = Math.Abs(x1-x2);
for(int i=0; i <= length; i++)
{
// step will go either from x1 to x2 or from x2 to x1.
int step = (x1 < x2) ? x1 + i : x2 + (length-i);
}

当然,您可以将整个循环封装在一个方法中,这样您就不必重复代码:

void ForLoopUnknownDirection(int start, int stop, Action<int> action)
{
int length = Math.Abs(start-stop);
for(int i=0; i <= length; i++)
{
int step = (start < stop) ? start + i : stop + (length-i);
action(step);
}
}

这样,你可以在数字之间做任何你想做的事情,同时只写一次循环代码。

查看rextester 上的实时演示

只需使用Math.Min()Math.Max()来选择下边界和上边界。

类似这样的东西:

int MinX = Math.Min(X1, X2);
int MaxX = Math.Max(X1, X2);
for (int x = MinX; x <= MaxX; x++) {
//code
}

也许可以提取这样的方法

private static IEnumerable<int> Step(int start, int end)
{
if (start < end)
{
for (int x = start; x <= end; x++)
yield return x;
}
else
{
for (int x = start; x >= end; x--)
yield return x;
}
}

然后你可以做

foreach (int x in Step(X1, X2))
{
/*code*/
}

使用方向增量(下面代码中的d)

var d = (x1 > x2) ? -1 : 1;
var i = x1;
while (i != x2)
{
//
// insert your code here
//
i = i + d;
}

我是purdy吗?😜

为什么这么复杂?

for (int n = 0; n < Count; n++)
{
int Index = (ascending ? n : Count - 1- n);
}