Can someone show me how to implement a recursive lambda expression to traverse a tree structure in C#.
Assuming a mythical object TreeItem, that conatins a Children collection to represent your hierarchy.
public void HandleTreeItems(Action<TreeItem> item, TreeItem parent)
{
if (parent.Children.Count > 0)
{
foreach (TreeItem ti in parent.Children)
{
HandleTreeItems(item, ti);
}
}
item(parent);
}
Now to call it, passing in the lambda that handles one item, by printing its name to the console.
HandleTreeItems(item => { Console.WriteLine(item.Name); }, TreeItemRoot);
@joelc,
Recursive lambda expression is not so trivial to implement (but not too hard either :) ), see following resources to get started:
Fun with recursive Lambda functions
What @ChanChan posted has nothing to do with recursive lamdas, it's just a recursive function that takes lambda expression as parameter.
@aku's links show the proper solution. A simple alternative is to “go back in time” to the antics of C and C++: declaration before definition. Try the following:
Func<int, int> fact = null;
fact = x => (x == 0) ? 1 : x * fact(x - 1);
Works like a charm.
A simple alternative is to “go back in time” to the antics of C and C++: declaration before definition. Try the following:
Func<int, int> fact = null; fact = x => (x == 0) ? 1 : x * fact(x - 1);
Works like a charm.
Yes, that does work, with one little caveat. C# has mutable reverences. So make sure you don't accidentally do something like this:
Func<int, int> fact = null;
fact = x => (x == 0) ? 1 : x * fact(x - 1);
// Make a new reference to the factorial function
Func<int, int> myFact = fact;
// Use the new reference to calculate the factorial of 4
myFact(4); // returns 24
// Modify the old reference
fact = x => x;
// Again, use the new reference to calculate
myFact(4); // returns 16
Of course, this example is a bit contrived, but this could happen when using mutable references. If you use the combinators from aku's links, this won't be possible.
Ok, I found some free time finally.
Here we go:
class TreeNode
{
public string Value { get; set;}
public List<TreeNode> Nodes { get; set;}
public TreeNode()
{
Nodes = new List<TreeNode>();
}
}
Action<TreeNode> traverse = null;
traverse = (n) => { Console.WriteLine(n.Value); n.Nodes.ForEach(traverse);};
var root = new TreeNode { Value = "Root" };
root.Nodes.Add(new TreeNode { Value = "ChildA"} );
root.Nodes[0].Nodes.Add(new TreeNode { Value = "ChildA1" });
root.Nodes[0].Nodes.Add(new TreeNode { Value = "ChildA2" });
root.Nodes.Add(new TreeNode { Value = "ChildB"} );
root.Nodes[1].Nodes.Add(new TreeNode { Value = "ChildB1" });
root.Nodes[1].Nodes.Add(new TreeNode { Value = "ChildB2" });
traverse(root);