66 votes

Expression lambda récursive pour parcourir un arbre en C #

Quelqu'un peut-il me montrer comment implémenter une expression lambda récursive pour parcourir une arborescence en C #.

80voto

aku Points 54867

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);
 

30voto

Konrad Rudolph Points 231505

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.

18voto

Tom Lokhorst Points 7733

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.

1voto

DevelopingChris Points 12510

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);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X