我正在用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);
}