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

时间:2017-10-28 04:25:05

标签: c# loops for-loop

我用C#编写图形程序,我无法找到在两个值之间运行for循环的好方法,其中任何一个可能比另一个更大或更小。

为了演示,当X2> X1:

时,以下代码可以正常工作
for (int x = X1; x<=X2; x++) {
    //code
}

然而,当X2

因为我正在做一个图形程序,当X2&lt; X1时,我不能简单地交换X1和X2 ,因为这意味着交换它们相关的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*/}
}

因复制代码而不合适,特别是如果&#34; // code&#34;部分特别长

#2:很多三元

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

虽然这段代码有效且简洁,但它的可读性非常糟糕。我也在各个地方看到使用&#34;不等于&#34;对于你的循环约束是不好的做法source

#3:使用while循环

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

这个解决方案看起来很漫长而且很复杂,可以执行这么简单的任务,另外,使用&#34; while(true)&#34;也是不好的做法source

6 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

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

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

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

See a live demo on rextester

答案 2 :(得分:1)

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

这样的事情:

int MinX = Math.Min(X1, X2);
int MaxX = Math.Max(X1, X2);

for (int x = MinX; x <= MaxX; x++) {
  //code
}

答案 3 :(得分:1)

也许提取这样的方法

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*/
}

答案 4 :(得分:0)

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

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

我是谁?

答案 5 :(得分:-1)

为什么这么复杂?

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