Home > Mobile >  Change iteration direction of for loop
Change iteration direction of for loop

Time:01-03

I want to iterate through some list items in such a way that I would start from a specific position and then go left from it, after that go right from it.

In other words, something like this:

var items = new List<string>() { "Item1", "Item2", "Item3", "Item4", "Item5" };
string item = "Item3";

int index = items.IndexOf(item);

for (int i = index; i >= 0; i--)
    yield return items[i];

for (int i = index   1; i < items.Count; i  )
    yield return items[i];

The result is: Item3, Item2, Item1, Item4, Item5

Is there a way to achieve this, but using only one for-loop?

Or is there some kind of conditional direction in LINQ?

CodePudding user response:

You could use the ternary if and some simple arithmetic on the index to achieve this.

for (int i = 0; i < items.Count; i  )
    yield return i <= index ? items[index - i] : items[i];

Result:

Item3
Item2
Item1
Item4
Item5

CodePudding user response:

You cannot use two returns at the same time using one loop, but it is possible to fetch data.

for (int i = index; i >= 0; i--)
{
   string answer1 = items[i]; //2,1,0
   if(items.Count - i < items.Count)
      string answer2 = items[items.Count - i]; // 3,4
}

CodePudding user response:

Something like this perhaps, with tuple deconstruction:

var items = new List<string>() { "Item1", "Item2", "Item3", "Item4", "Item5" };
string item = "Item3";

int index = items.IndexOf(item);

for ((int i, int j) = (index, 0); j < items.Count; i--, j  ){
    if(i>=0){
       yield return items[i];
    } else {
       yield return item[j];
    }
}

CodePudding user response:

Another solution using the pythonic way would be by generating the sequence of indexes using Enumerable.Range.

foreach (int i in Enumerable.Range(0, index   1).Reverse().Union(Enumerable.Range(index   1, items.Count - index - 1)))
    yield return items[i];

But in terms of performance and maintainability, I would go with your existing solution using two separate for-loops.

In terms of making the intent of your code more clearly, I would go with items.Take(3).Reverse().Concat(items.Skip(3)) as it says directly what will happen.

  • Related