Popular Posts

Saturday, June 11, 2011

Linq Recursive Extensions

Here are some extension methods to allow you to recurse through a class hierarchy:
    public static class LinqExtensions
    {
        public static IEnumerable<T> Recurse<T>(this T source, Func<T, IEnumerable<T>> getChildren) where T : class
        {
            if (source == null)
                return new List<T>();
 
            List<T> result = getChildren(source).Recurse<T>(getChildren).ToList();
            result.Insert(0, source);
             
            return result;
        }
 
        public static IEnumerable<T> Recurse<T>(this T source, Func<T, T> getChild) where T : class
        {
            if (source != null)
                yield return source;
 
            T child = getChild(source);
            while (child != null)
            {
                yield return child;
                child = getChild(child);
            }
        }
 
        public static IEnumerable<T> Recurse<T>(this IEnumerable<T> source, Func<T, T> getChild) where T : class
        {
            List<T> result = new List<T>();
            if (source != null)
            {
                foreach (T child in source)
                    result.AddRange(child.Recurse<T>(getChild));
            }
             
            return result;
        }
 
        public static IEnumerable<T> Recurse<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> getChildren) where T : class
        {
            if (source != null)
            {
                foreach (T child in source)
                {
                    if (child != null)
                        yield return child;
 
                    IEnumerable<T> subChildren = getChildren(child);
                    if (subChildren != null)
                    {
                        foreach (T subChild in subChildren.Recurse<T>(getChildren))
                        {
                            if (subChild != null)
                                yield return subChild;
                        }
                    }
                }
            }
        }
    }

Here's an example of how to use them:
    public class Node
    {
      public List<Node> Children = new List<Node>();
    }

    Node parent = new Node();
    IEnumerable<Node> children = parent.Recurse(x => x.Children);

No comments:

Post a Comment