Skip to content

Instantly share code, notes, and snippets.

@benjamin-bader
Created April 24, 2012 00:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benjamin-bader/2474986 to your computer and use it in GitHub Desktop.
Save benjamin-bader/2474986 to your computer and use it in GitHub Desktop.
Interleave operator
public static IEnumerable<T> Interleave<T>(this IEnumerable<T> collection, IEnumerable<T> other, int thisCount, int thatCount)
{
if (collection == null)
throw new ArgumentNullException("collection");
if (other == null)
throw new ArgumentNullException("other");
if (thisCount < 1)
throw new ArgumentOutOfRangeException("thisCount", thisCount, "Must be greater than zero.");
if (thatCount < 1)
throw new ArgumentOutOfRangeException("thatCount", thatCount, "Must be greater than zero.");
using (var thisEnumerator = collection.GetEnumerator())
using (var thatEnumerator = other.GetEnumerator())
{
var hasThis = true;
var hasThat = true;
// Alternate between enumerators as long as both have elements left.
while (hasThis && hasThat)
{
var takenFromThis = 0;
while (takenFromThis < thisCount && (hasThis = thisEnumerator.MoveNext()))
{
yield return thisEnumerator.Current;
++takenFromThis;
}
var takenFromThat = 0;
while (takenFromThat < thatCount && (hasThat = thatEnumerator.MoveNext()))
{
yield return thatEnumerator.Current;
++takenFromThat;
}
}
// One of the two is exhausted, just read from whichever one isn't
// for the remainder of the sequence.
if (hasThis)
{
while (thisEnumerator.MoveNext())
yield return thisEnumerator.Current;
}
if (hasThat)
{
while (thatEnumerator.MoveNext())
yield return thatEnumerator.Current;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment