2011-02-03 17 views
5

多くの要素を持つ2つ以上のIEnumerable<T>があるとします。 IEnumerableには別のタイプのTがあります。リストは極端に長くなる可能性があり、完全にメモリにロードすべきではありません。私が何をしたいか複数のIEnumerableを同時に繰り返し処理する方法

IEnumerable<int> ints = getManyInts(); 
IEnumerable<string> strings = getSomeStrings(); 
IEnumerable<DateTime> dates = getSomeDates(); 

は最長の終わりまたは最短リストに達するまで、これらのリストを反復処理し、各ステップのために1つのint型、1つの文字列と1のDateTimeを含むアイテムを取得することです。両方のケースをサポートする必要があります(bool param longest vs. shortest or so)。より短いリストで利用できないすべてのアイテムについては(すでに終了しているため)、私はデフォルト値を期待しています。

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

遅延実行を使用してlinqでこれを行うことはできますか? IEnumeratorsとyield returnを直接組み合わせたソリューションが分かります。 (未テスト警告 - )は、このようなHow can I iterate over two IEnumerables simultaneously in .NET 2

+0

あなたは以上の2つのパラメータを受け入れる 'Zip'機能を探しています。 – Gabe

+0

あなたは 'var result = s1.Zip(s2.Zip(s3、(a、b)=> new {a、b})、(a、b)=> new {a = a 、b = ba、c = bb}); ' – Mormegil

+0

s2が最長リストであり、s1の要素がほとんどない場合はどうなりますか? –

答えて

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); 
    } 
} 
+0

はい、それは私の質問の終わりに意味したものです。私はperformant linqメソッドがあることを望んだ。 –

+0

@matthias - これはlinqと互換性があり、他のlinq演算子と同じように動作します。 –

+0

私はこれがLinqと互換性があることを知っています。別のIEnumerableを単に返すだけです。 –

関連する問題