【问题标题】:Change iteration direction of for loop改变for循环的迭代方向
【发布时间】:2022-01-03 09:20:05
【问题描述】:

我想以这样一种方式遍历一些列表项,即从特定位置开始,然后从它向左走,然后从它向右走。

换句话说,是这样的:

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 会导致3,4,5,1,2,而不是3,2,1,4,5
  • 我会选择items.Take(3).Reverse().Concat(items.Skip(3))
  • 你为什么要这个?您当前的解决方案是有效的、可读的并且只对您的列表进行一次迭代。任何 LINQ 解决方案都会多次迭代您的项目,没有 LINQ 的解决方案会损害可读性。

标签: c# list for-loop


【解决方案1】:

您可以使用三元 if 和索引上的一些简单算术来实现这一点。

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

结果:

Item3
Item2
Item1
Item4
Item5

【讨论】:

  • 天啊,这么聪明,这么简单……谢谢!
【解决方案2】:

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

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,它将触发超出范围异常
  • 有条件 if(items.Count - i
【解决方案3】:

可能是这样的,带有元组解构:

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

【讨论】:

    【解决方案4】:

    使用 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 除了做(但)antoher 迭代之外什么都不值得。但是感谢合并 python 逻辑和 C# 编码:)
    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 2017-08-23
    • 1970-01-01
    相关资源
    最近更新 更多