Edit: Corrected the code, I did in fact compile and test both pieces of code, but I must've pasted in versions before I fixed them in VS. Sorry about that.
I've added a Subversion repository with the code, including unit tests, to ensure it now works as expected, is here, log in with username and password both as 'guest', without the quotes.
Like this:
1: Find first
Func<TreeNode, String, TreeNode> findNode = null; // satisfy recursion re-use
findNode = (n, value) =>
{
if (n == null) return n;
if (n.Value == value) return n;
foreach (var subNode in n.Nodes)
{
TreeNode foundNode = findNode(subNode, value);
if (foundNode != null) return foundNode;
}
return null;
};
Note that the trap here is that for a lambda or a delegate to be recursive, you need to declare the variable first, with a known value, before you assign the actual delegate to it. Otherwise the compiler will complain that you're using a variable before it has been given a value.
2: Find all
Func<TreeNode, String, List<TreeNode>> findNodes = null;
findNodes = (n, value) =>
{
var result = new List<TreeNode>();
if (n == null) return result;
if (n.Value == value) result.Add(n);
foreach (var subNode in n.Nodes)
{
result.AddRange(findNodes(subNode, value));
}
return result;
};
The trick is here to just gather up the nodes on each level, and aggregate upwards.