recursionlambdaexpression式遍历C#中的一棵树
有人可以告诉我如何实现recursionlambdaexpression式来遍历C#中的树结构。
好的,我终于find了一些空闲时间。
开始了:
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);
一个适当的解决scheme,以及许多函数式编程语言的惯用解决scheme将是使用一个定点组合器 。 简而言之:定点组合器回答了“我如何定义一个匿名函数recursion?”的问题。 但是这个解决scheme太不重要了,整个文章都是为了解释它们而写的。
一个简单而实用的select就是在定义之前把C:声明的滑稽动作“回溯”回去。 尝试以下操作:
Func<int, int> fact = null; fact = x => (x == 0) ? 1 : x * fact(x - 1);
奇迹般有效。
一个简单的select就是“定时返回”到C和C ++的antics:定义之前的声明。 尝试以下操作:
Func<int, int> fact = null; fact = x => (x == 0) ? 1 : x * fact(x - 1);
奇迹般有效。
是的,这是有用的,只有一点警告。 C#有可变引用。 所以请确保你不会不小心做到这样的事情:
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 12
当然,这个例子是有点人为的,但是在使用可变引用时会发生这种情况。 如果你从aku的链接中使用组合器,这是不可能的。
假设一个神话对象TreeItem,它包含一个Children集合来表示您的层次结构。
public void HandleTreeItems(Action<TreeItem> item, TreeItem parent) { if (parent.Children.Count > 0) { foreach (TreeItem ti in parent.Children) { HandleTreeItems(item, ti); } } item(parent); }
现在调用它,传入处理一个项目的lambda,通过将其名称打印到控制台。
HandleTreeItems(item => { Console.WriteLine(item.Name); }, TreeItemRoot);