如何同时迭代几个IEnumerables

mat*_*zek 5 .net linq performance foreach deferred-execution

假设我有两个(或更多)IEnumerable<T>元素.每个IEnumerable都有另一种类型T.列表可能非常长,不应完全加载到内存中.

IEnumerable<int> ints = getManyInts();
IEnumerable<string> strings = getSomeStrings();
IEnumerable<DateTime> dates = getSomeDates();
Run Code Online (Sandbox Code Playgroud)

我想要做的是迭代这些列表,并获得一个包含一个int,一个字符串和每个步骤一个DateTime的项目,直到达到最长或最短列表的末尾.两种情况都应该得到支持(bool param最长与最短等).对于较短列表中不可用的每个项目(因为已经达到结束),我希望默认值.

for(Tuple<int,string,DateTime> item in 
    Foo.Combine<int,string,DateTime>(ints, strings, dates))
{
    int i=item.Item1;
    string s=item.Item2;
    DateTime d=item.Item3;
}
Run Code Online (Sandbox Code Playgroud)

是否可以使用延迟执行linq执行此操作?我知道使用IEnumerator直接结合yield return的解决方案.请参阅如何在.NET 2中同时迭代两个IEnumerables

Joe*_*orn 4

像这样的事情应该可以做到(警告-未经测试):

public static IEnumerable<Tuple<T, U, V>> IterateAll<T, U, V>(IEnumerable<T> seq1, IEnumerable<U> seq2, IEnumerable<V> seq3)
{
    bool ContinueFlag = true;
    using (var e1 = seq1.GetEnumerator())
    using (var e2 = seq2.GetEnumerator())
    using (var e3 = seq3.GetEnumerator())
    {
        do
        {
            bool c1 = e1.MoveNext();
            bool c2 = e2.MoveNext();
            bool c3 = e3.MoveNext();
            ContinueFlag = c1 || c2 || c3;

            if (ContinueFlag)
                yield return new Tuple<T, U, V>(c1 ? e1.Current : default(T), c2 ? e2.Current : default(U), c3 ? e3.Current : default(V));
        } while (ContinueFlag);
    }
}
Run Code Online (Sandbox Code Playgroud)