How to “zip” or “rotate” a variable number of lists?

You can roll your own ZipMany instance which manually iterates each of the enumerations. This will likely perform better on larger sequences than those using GroupBy after projecting each sequence:

public static IEnumerable<TResult> ZipMany<TSource, TResult>(
    IEnumerable<IEnumerable<TSource>> source,
    Func<IEnumerable<TSource>, TResult> selector)
{
   // ToList is necessary to avoid deferred execution
   var enumerators = source.Select(seq => seq.GetEnumerator()).ToList();
   try
   {
     while (true)
     {
       foreach (var e in enumerators)
       {
           bool b = e.MoveNext();
           if (!b) yield break;
       }
       // Again, ToList (or ToArray) is necessary to avoid deferred execution
       yield return selector(enumerators.Select(e => e.Current).ToList());
     }
   }
   finally
   {
       foreach (var e in enumerators) 
         e.Dispose();
   }
}

Leave a Comment