1

無制限の子を持つことができるカテゴリがあり、各子も無制限の子を持つことができると仮定します。

興味深いことに、LINQ を使用してルート ノードのすべてのファミリを取得する方法はありますか?

4

2 に答える 2

2

C# で再帰構造を処理するにはyield return、再帰関数を使用する方法と記述する方法の 2 つの一般的な方法があります。私は 2 番目の方法を好みます。例を次に示します。

public static class TreeUtils {
    public static IEnumerable<T> GetAllNodes<T>(
        this T node
    ,   Func<T,IEnumerable<T>> f) 
    {
        return GetAllNodes(new[] {node}, f);
    }
    public static IEnumerable<T> GetAllNodes<T>(
        this IEnumerable<T> e
    ,   Func<T,IEnumerable<T>> f) 
    {
        return e.SelectMany(c => f(c).GetAllNodes(f)).Concat(e);
    }
}

このユーティリティ クラスは次のように使用できます。

class TreeNode<T> {
    public T Content {get; set;}
    public IEnumerable<TreeNode<T>> Dependents {get;set;}
}

foreach (TreeNode node in TreeUtils.GetAllNodes(root, n => n.Dependents)) {
    Console.WriteLine(node.Content);
}

「再帰的な」ラムダを使用するのは、やや不正な方法です。

using System;
using System.Collections.Generic;

public class Program {
    class Node {
        public int Data;
        public IEnumerable<Node> Dependents { get; set; }
    }
    public static void Main() {
        var root = Create(
            10
        ,   Create(5, Create(3), Create(7, Create(6), Create(8)))
        ,   Create(20, Create(15), Create(30, Create(28), Create(40)))
        );
        // We cannot combine the declaration and definition here
        Func<Node,IEnumerable<Node>> all = null;
        // The recursive magic is in the following line
        all = n => n.Dependents.SelectMany(d => all(d)).Concat(new[] {n});
        // Here is how you can use it
        foreach (var node in all(root)) {
            Console.WriteLine(node.Data);
        }
    }
    // Helper function for creating tree nodes
    private static Node Create(int data, params Node[] nodes) {
        return new Node { Data = data, Dependents = nodes };
    }
}
于 2012-08-08T16:10:15.397 に答える
1

linq が非常に依存しているラムダは、直感的な方法でそのようなことを行うために必要な再帰をサポートしていません。ただし、let と y コンビネーターを使用すると、非直感的な方法でそれを行うことができます。複雑な例を次に示します。

http://blogs.msdn.com/b/lukeh/archive/2007/10/01/take-linq-to-objects-to-extremes-a-fully-linqified-raytracer.aspx

うまくいけば、誰かがより簡潔なものを考え出すでしょう。もしそうなら、それらを選んでください。

于 2012-08-08T16:09:26.460 に答える