Greg Gum Greg Gum - 1 month ago 14
C# Question

How to search Hierarchical Data with Linq

I need to search a tree for data that could be anywhere in the tree. How can this be done with linq?

class Program
{
static void Main(string[] args) {

var familyRoot = new Family() {Name = "FamilyRoot"};

var familyB = new Family() {Name = "FamilyB"};
familyRoot.Children.Add(familyB);

var familyC = new Family() {Name = "FamilyC"};
familyB.Children.Add(familyC);

var familyD = new Family() {Name = "FamilyD"};
familyC.Children.Add(familyD);

//There can be from 1 to n levels of families.
//Search all children, grandchildren, great grandchildren etc, for "FamilyD" and return the object.


}
}

public class Family {
public string Name { get; set; }
List<Family> _children = new List<Family>();

public List<Family> Children {
get { return _children; }
}
}

Answer

That's an extension to It'sNotALie.s answer.

public static class Linq
{
    public static IEnumerable<T> Flatten<T>(this T source, Func<T, IEnumerable<T>> selector)
    {
        return selector(source).SelectMany(c => Flatten(c, selector))
                               .Concat(new[] { source });
    }
}

Sample test usage:

var result = familyRoot.Flatten(x => x.Children).FirstOrDefault(x => x.Name == "FamilyD");

Returns familyD object.

You can make it work on IEnumerable<T> source too:

public static IEnumerable<T> Flatten<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
{
    return source.SelectMany(x => Flatten(x, selector))
        .Concat(source);
}