Jason Rowe

Be curious! Choose your own adventure.

Recursive LINQ Query Example

I found this Traverse extension post on MSDN while searching for a good recursion example in Linq. I know it’s a little dated but Hey! We all learn at our own pace and mine is a little sloooower when it comes to Linq

I really got a lot out of this code snippet in terms of patterns and syntax. It makes use of some goodies like Delegates, Linq, and IEnumerable. The most interesting part for me though was the recursive call inside the Traverse extension and what it was being used for.

It shows a good pattern for getting values out of nested objects or flatting. Here is a quick sample app using the Traverse extension. Below this I’ve posted some other sources with similar selection patterns.

Link to code with syntax highlighting

class Program
{
static void Main()
{
    var list = new List {new MyClass(10), new MyClass(20)};

    foreach(var l in list)
    {
        l.MyList = new List {new MyClass(10)};
    }
    
    var total = list.Traverse(x => x.MyList).Sum(x => x.Val);

    Console.WriteLine(total);
    Console.ReadLine();
}
}
public static class MyExtensions
{
//The Traverse extension can be added to types of IEnumerable.
//Returns T
//Input Param
//"fnRecurse" - delegate with one parameter T and returns IEnumerable

public static IEnumerable Traverse
       (this IEnumerable source, Func> fnRecurse)
{
    foreach (T item in source)
    {
        yield return item;

        var seqRecurse = fnRecurse(item);

        if (seqRecurse != null)
        {

//Making Recursive call to Traverse using 
//results from the lambda expression 
            foreach (T itemRecurse in Traverse(seqRecurse, fnRecurse))
            {
                yield return itemRecurse;
            }
        }
    }
}
}

public class MyClass
{
public MyClass(int val)
{
    Val = val;
}

public int Val;
public List MyList = new List();
}

Here are some more posts on the same topic:


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *