Guest User

C# LINQ Interleave implementation

a guest
Sep 15th, 2011
356
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.30 KB | None | 0 0
  1.         /// <summary>
  2.         /// Returns a new sequence that contains elements from the first sequence interleaved with elements from the second sequence.
  3.         /// </summary>
  4.         /// <typeparam name="T">The type of elements in the input sequences.</typeparam>
  5.         /// <param name="first">The first input sequence.</param>
  6.         /// <param name="second">The second input sequence.</param>
  7.         /// <returns>A new sequence that contains elements from the first sequence interleaved with elements from the second sequence.</returns>
  8.         public static IEnumerable<T> InterleaveWith<T>(this IEnumerable<T> first, IEnumerable<T> second)
  9.         {
  10.             return first.InterleaveWith(second, 1, 1);
  11.         }
  12.  
  13.         /// <summary>
  14.         /// Returns a new sequence that contains groups of elements from the first sequence
  15.         /// interleaved with groups of elements from the second sequence.
  16.         /// </summary>
  17.         /// <typeparam name="T">The type of elements in the input sequences.</typeparam>
  18.         /// <param name="first">The first input sequence.</param>
  19.         /// <param name="second">The second input sequence.</param>
  20.         /// <param name="firstSequenceGroupSize">The consecutive number of items in groups of items from the first sequence.</param>
  21.         /// <param name="secondSequenceGroupSize">The consecutive number of items in groups of items from the second sequence.</param>
  22.         /// <returns>A new sequence that contains groups of elements from the first sequence interleaved with groups of elements from the second sequence.</returns>
  23.         public static IEnumerable<T> InterleaveWith<T>(this IEnumerable<T> first, IEnumerable<T> second, int firstSequenceGroupSize, int secondSequenceGroupSize)
  24.         {
  25.             using (var firstIterator = first.GetEnumerator())
  26.             using (var secondIterator = second.GetEnumerator())
  27.             {
  28.                 var exhaustedFirst = false;
  29.  
  30.                 // Keep going while we've got elements in the first sequence.
  31.                 while (!exhaustedFirst)
  32.                 {
  33.                     for (var i = 0; i < firstSequenceGroupSize; i++) {
  34.                         if (!firstIterator.MoveNext()) {
  35.                             exhaustedFirst = true;
  36.                             break;
  37.                         }
  38.  
  39.                         yield return firstIterator.Current;
  40.                     }
  41.  
  42.                     // This may not yield any results - the first sequence
  43.                     // could go on for much longer than the second. It does no
  44.                     // harm though; we can keep calling MoveNext() as often
  45.                     // as we want.
  46.                     for (var i = 0; i < secondSequenceGroupSize; i++)
  47.                     {
  48.                         // This is a bit ugly, but it works...
  49.                         if (!secondIterator.MoveNext()) {
  50.                             break;
  51.                         }
  52.  
  53.                         yield return secondIterator.Current;
  54.                     }
  55.                 }
  56.  
  57.                 // We may have elements in the second sequence left over.
  58.                 // Yield them all now.
  59.                 while (secondIterator.MoveNext()) {
  60.                     yield return secondIterator.Current;
  61.                 }
  62.             }
  63.         }
Advertisement
Add Comment
Please, Sign In to add comment