Friday, September 23, 2011

Recursion in Linq

Being able to traverse a tree structure can be very handy, or flatten a tree to a list. Linq doesn't offer this out of the box, but it's a fairly straightforward extension to add.


/// <summary>
/// Recusively traverse a tree structure
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="collection"></param>
/// <param name="childrenSelector">Child navigation property on T</param>
/// <returns>Flattened collection</returns>
public static IEnumerable<T> Traverse<T>(this IEnumerable<T> collection, Func<T, IEnumerable<T>> childrenSelector)
{
    foreach (var item in collection)
    {
        yield return item;

        var children = childrenSelector(item);

        if (children != null)
        {
            foreach (var child in Traverse(children, childrenSelector))
            {
                yield return child;
            }
        }
    }
}

The source is pretty much straight from here, with an extra check against null children collections.