改变for循环的迭代方向

3
我想遍历一些列表项,以特定位置为起点先向左再向右。
换句话说,就是这样:
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];

结果是:Item3Item2Item1Item4Item5
是否有一种方法可以使用一个for循环来实现这个结果?
或者LINQ中是否有某种条件方向?

类似于 items.Skip(2).Concat(items.Take(2)) 这样的东西? - C.Evenhuis
@C.Evenhuis 这将导致 3,4,5,1,2,而不是 3,2,1,4,5 - Rafalon
4
我会选择 items.Take(3).Reverse().Concat(items.Skip(3)) - Rafalon
5
你为什么想要这样做?你现在的解决方案已经有效、易读,并且只对列表进行了一次迭代。任何使用LINQ的解决方案都会对你的项进行多次迭代,而没有使用LINQ的解决方案则会影响可读性。 - Bill Tür stands with Ukraine
刚刚看了这篇帖子,问题是“有没有一种方法可以只使用一个for循环来实现这个?” ;) - Nicolas Voron
显示剩余2条评论
4个回答

10
你可以使用三元操作符和简单的算术运算符来处理索引以实现此目的。
for (int i = 0; i < items.Count; i++)
    yield return i <= index ? items[index - i] : items[i];

结果:

Item3
Item2
Item1
Item4
Item5

1
哇,如此聪明而简单...谢谢! - Sandra Guerrero

0

你不能在同一循环中同时使用两个返回,但可以获取数据。

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
}

这个怎么工作?如果 items.Count 是奇数或者 index != items.Count / 2,它将触发一个超出范围的异常。 - Rafalon
如果(items.Count - i < items.Count)的条件成立 - Meysam Asadi

0

另一种使用“Pythonic”方式的解决方案是通过使用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];

但就性能和可维护性而言,我会选择您现有的解决方案,使用两个单独的for循环

为了使您的代码意图更加清晰,我会选择items.Take(3).Reverse().Concat(items.Skip(3)),因为它直接说明了将发生什么。


在这种情况下,您应该只返回LINQ结果,foreach循环没有做任何事情(尚未)再进行迭代。但由于合并了Python逻辑和C#编码 :) - Nicolas Voron

0

或许可以像这样,使用元组解构:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接