【问题标题】:Is there a way to do a foreach on each element pair in 2 IEnumerable's in C#?有没有办法在 C# 中对 2 个 IEnumerable 中的每个元素对进行 foreach?
【发布时间】:2010-10-26 18:34:30
【问题描述】:

我可以将它们转换为列表并使用带有索引的常规 for 循环,但我想知道是否有办法将它们保持为 IEnumerables。

【问题讨论】:

    标签: c# foreach ienumerable


    【解决方案1】:

    我认为您需要 .NET 4.0 的新 Zip 功能。 Eric Lippert blogged about it recently 并包含了一个简单的实现形式。

    它也在MoreLINQZip.cs 中,如果序列长度不同,则允许使用不同的选项。 “默认”是像 .NET 4.0 一样,当任一序列用完元素时停止。替代方法是填充较短的序列或抛出异常。

    【讨论】:

    • 是的,这是我这周以来真正喜欢 Python 的地方之一,所以我使用它的是 Zip 是一个内置函数,很少有传统的情况需要 for 循环,他们强调,通过让你必须做一个小黑客来获得传统的 for 循环行为。很高兴看到它将成为 int C#4
    【解决方案2】:

    默认情况下没有办法,但添加扩展方法使其更容易一点并不难。为了简洁起见,我排除了一些错误检查以确保它们的长度相同。

    public static void ForEachPair<T1,T2>(
      this IEnumerable<T1> source1, 
      IEnumerable<T2> source2,
      Action<T1,T2> del) {
      using ( var e1 = source1.GetEnumerator() )
      using ( var e2 = source2.GetEnumerator() ) {
        while ( e1.MoveNext() && e2.MoveNext() ) {
          del(e1.Current, e2.Current);
        }
      }
    }
    

    现在您可以执行以下操作

    var list = GetSomeList();
    var otherList = GetSomeOtherList();
    list.ForEachPair(otherList, (x,y) => 
    {
       // Loop code here
    });
    

    【讨论】:

    • @Jared:我认为你的意思是你的“如果”是“一段时间”。 @leppie:除了将结果作为 IEnumerable(然后您可以使用 foreach 对其进行操作)而不是传递委托来执行之外,这与“Zip”有何不同?
    • 那里有用的小功能。小建议:不需要嵌套using语句。
    • Jon 似乎对 while 循环也是正确的。希望您不介意编辑。
    • @Noldorin,它们要么必须嵌套,要么必须使用 try/finally。如果没有嵌套它们,你将如何实现这一点?是的,@Jon 是对的(感谢更新)
    • 如果声明的类型相同,则不需要“嵌套”它们。 "使用(Foo foo1 = GetFoo(), foo2 = GetAnotherFoo()) 语句;"是“using(Foo foo1 = GetFoo()) using (Foo foo2 = GetAnotherFoo) 语句的语法糖;” (但你不能在多重声明表中使用“var”。)
    猜你喜欢
    • 2020-03-16
    • 1970-01-01
    • 2018-12-20
    • 2020-02-09
    • 2011-02-26
    • 2017-02-08
    • 2012-09-15
    • 2022-01-27
    • 2022-01-19
    相关资源
    最近更新 更多