Flatten an enumerable recursively

/// <summary>
/// Flatten an enumerable recursively.
/// </summary>
/// <remarks>A bit like SelectMany.</remarks>
/// <typeparam name="T"></typeparam>
/// <param name="enumerable"></param>
/// <param name="enumerableSelector"></param>
/// <returns>A new sequence of T</returns>
public static IEnumerable<T> FlattenDeep<T>(this IEnumerable<T> enumerable,
    Func<T, IEnumerable<T>> enumerableSelector)
{
    foreach (var element in enumerable)
    {
        yield return element;

        var candidate = enumerableSelector(element);

        if (candidate == null) continue;

        var children = FlattenDeep(candidate, enumerableSelector);

        foreach (var child in children)
        {
            yield return child;
        }
    }
}

 

Leave a Reply