Ternary operator in actualization of a loop

1.7k views Asked by At

I am trying to make two loops into one. This Loop should go through the array from the beginning to the end and otherwise. However my increment is not correct. Can anyone help? Thank you in advance.

for (int i = ((asc == true) ? 0 : calendar.Length - 1);
    ((asc == true) ? i < calendar.Length : i > 0); 
    (asc==true) ? i++ : i--)
4

There are 4 answers

1
Griffin On BEST ANSWER

Look at the C# reference of "for": http://msdn.microsoft.com/en-us/library/ch45axte.aspx

Specifically:

The iterator section defines what happens after each iteration of the body of the loop. The iterator section contains zero or more of the following statement expressions, separated by commas:

  • assignment statement
  • invocation of a method
  • prefix or postfix increment expression, such as ++i or i++
  • prefix or postfix decrement expression, such as --i or i--
  • creation of an object by using new
  • await expression

The expression: "(asc==true) ? i++ : i--" is none of these things.

Therefore, you'd want the assignment: i += (asc ? 1 : -1)

for (int i = ((asc) ? 0 : calendar.Length - 1);
      ((asc) ? i < calendar.Length : i >= 0); 
      i += (asc) ? 1 : -1)

Incidentally, as pointed out in comment, you'll probably want to look at index 0 in the condition, so your condition statement in the "descending" case should be i >= 0 (reflected in the code).

4
Jon Skeet On

Personally, I find that very hard to read, as well as invalid (it won't compile) - because you're trying to use the conditional operator as a statement expression, when it's not. Personally, I'd write something like:

for (int i = 0; i < calendar.Length; i++)
{
    int index = asc ? i : calendar.Length - 1 - i;
    // Now use index...
}

Making three different aspects all conditional feels like a nasty way to go.

0
BradleyDotNET On

That for loop is... odd. It is also very hard to read. In the spirit of "better ways to do this", I would suggest just using Reverse:

IEnumerable<Day> collection = asc ? calendar : calendar.Reverse();

for (int i = 0; i < calendar.Length; i++)
{
    collection.ElemantAt(i);// This is the current element
}

//Or better, you are getting everything anyways:
foreach (Day day in collection)
{
}
2
Evgeniy Mironov On

Jon offered a good option, but if principle:

for (int i = (asc ? 0 : calendar.Length - 1);
     asc ? i < calendar.Length : i >= 0; 
     i += asc?1:-1)
{
            //body
}