Skip to content

Instantly share code, notes, and snippets.

@Alvtron
Last active November 25, 2020 07:10
Show Gist options
  • Save Alvtron/c3e72de09b781db77b94dc680809d21b to your computer and use it in GitHub Desktop.
Save Alvtron/c3e72de09b781db77b94dc680809d21b to your computer and use it in GitHub Desktop.
Split enumerable into two based on predicate.
public static class EnumerableSplitExtensions
{
/// <summary>
/// Splits the enumerable into two separate sequences based on predicate.
/// </summary>
/// <remarks>
/// This is more efficient than using two Where()-filters (from LINQ) because the source is only enumerated one time. Testing reveals an approximate 30% speed increase.
/// </remarks>
/// <typeparam name="TSource">The type of the elements in the enumerable.</typeparam>
/// <param name="source">The source of elements.</param>
/// <param name="predicate">The predicate which splits the enumerable.</param>
/// <param name="matched">The return source of elements that match the predicate.</param>
/// <param name="unmatched">The return source of elements that does not match the predicate.</param>
public static void Split<TSource>(this IEnumerable<TSource> source, Predicate<TSource> predicate, out IList<TSource> matched, out IList<TSource> unmatched)
{
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
if (predicate is null)
{
throw new ArgumentNullException(nameof(predicate));
}
matched = new List<TSource>();
unmatched = new List<TSource>();
foreach (var element in source)
{
if (predicate(element))
{
matched.Add(element);
}
else
{
unmatched.Add(element);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment