Skip to content

Instantly share code, notes, and snippets.

@snay2
Created September 12, 2017 17:47
Show Gist options
  • Save snay2/da07df8268fb99e9b8d5bec02f46021d to your computer and use it in GitHub Desktop.
Save snay2/da07df8268fb99e9b8d5bec02f46021d to your computer and use it in GitHub Desktop.
/// <summary>
/// Iterate over each IEnumerable, returning items in parallel from first and second.
/// When one collection runs out of items, return default(T) instead until the other collection runs out as well.
/// For example, if first contains {1, 2, 3, 4} and second contains {5, 6}, operation will be called with the following values:
/// (1, 5)
/// (2, 6)
/// (3, 0)
/// (4, 0)
/// </summary>
/// <typeparam name="T">Usually string, but can be any type</typeparam>
/// <param name="first">First collection of items</param>
/// <param name="second">Second collection of items</param>
/// <param name="operation">Action to be called with one item from first and one item from second</param>
/// <param name="transform">(optional) Function to transform input into output (such as escaping XML because the output will be HTML)</param>
private static void MultipleForEach<T>(IEnumerable<T> first, IEnumerable<T> second, Action<T, T> operation, Func<T, T> transform = null)
{
if (transform == null)
{
// Use the identity function if none was provided
transform = x => x;
}
using (var firstEnumerator = first.GetEnumerator())
using (var secondEnumerator = second.GetEnumerator())
{
var firstHasMore = firstEnumerator.MoveNext();
var secondHasMore = secondEnumerator.MoveNext();
while (firstHasMore || secondHasMore)
{
var firstLine = firstHasMore ? transform(firstEnumerator.Current) : default(T);
var secondLine = secondHasMore ? transform(secondEnumerator.Current) : default(T);
operation.RunAction(firstLine, secondLine);
firstHasMore = firstEnumerator.MoveNext();
secondHasMore = secondEnumerator.MoveNext();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment