Quelqu'un peut-il me montrer comment implémenter une expression lambda récursive pour parcourir une arborescence en C #.
Réponses
Trop de publicités? Ok, j'ai enfin trouvé du temps libre.
Et c'est parti:
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);
Les liens de @ aku indiquent la solution appropriée. Une alternative simple consiste à "remonter dans le temps" aux singeries de C et C ++: déclaration avant définition. Essayez ce qui suit:
Func<int, int> fact = null;
fact = x => (x == 0) ? 1 : x * fact(x - 1);
Fonctionne comme un charme.
Une alternative simple est de "remonter le temps" pour les pitreries de C et C++: déclaration avant de définition. Essayez les solutions suivantes:
Func<int, int> fact = null; fact = x => (x == 0) ? 1 : x * fact(x - 1);
Fonctionne comme un charme.
Oui, ça fonctionne, avec un peu de mise en garde. C# a mutable références. Donc, assurez-vous que vous n'avez pas accidentellement faire quelque chose comme ceci:
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
Bien sûr, cet exemple est un peu tiré par les cheveux, mais cela pourrait se produire lors de l'utilisation mutable références. Si vous utilisez les combinators d' aku'des liens, ce ne sera pas possible.
En supposant un objet mythique TreeItem, cela conatine une collection Children pour représenter votre hiérarchie.
public void HandleTreeItems(Action<TreeItem> item, TreeItem parent)
{
if (parent.Children.Count > 0)
{
foreach (TreeItem ti in parent.Children)
{
HandleTreeItems(item, ti);
}
}
item(parent);
}
Maintenant, appelons-le en passant le lambda qui gère un élément en imprimant son nom sur la console.
HandleTreeItems(item => { Console.WriteLine(item.Name); }, TreeItemRoot);