2

次のような文字列があります。

/Test Town
/Test Town/Interior
/Test Dungeon/Secret

パスの任意のリストが与えられた場合、葉ノードを自動的に生成するにはどうすればよいですか? 解決策には再帰が含まれると思いますが、うまくいきません。

ループを使用してやろうとしましたが、最初のレベルしか取得できませんでした。

上記は次のようなものを生成します:

ここに画像の説明を入力

4

1 に答える 1

4

これはかなりうまく機能します。

まず、ツリー構造を作成する必要がありました。

public class Tree<T> : List<Tree<T>>
{
    public Tree(T value, IEnumerable<Tree<T>> children)
    {
        this.Value = value;
        this.AddRange(children);
    }
    public T Value { get; set; }
}

ここで、ツリーを構築するための再帰関数が必要になりました。

Func<
    IEnumerable<IEnumerable<string>>,
    IEnumerable<Tree<string>>>
        buildTree = null;

buildTree = xss =>
    xss
        .ToLookup(xs => xs.FirstOrDefault(), xs => xs.Skip(1))
        .Where(xs => xs.Key != null)
        .Select(xs => new Tree<string>(xs.Key, buildTree(xs)));

次に、lines変数に文字列のリストがあるので、実行する必要がありました。

var tree =
    buildTree(lines
        .Select(x => new [] { "Root", }.Concat(x.Split('/').Skip(1))));

以上です。Tree<T>クラスを数えなければ、これはわずか 3 行のコードです。単純。


別の方法として、匿名メソッドを使用したくない場合は、ツリー クラスを次のように変更できます。

public class Tree<T> : List<Tree<T>>
{
    public Tree(T value, IEnumerable<IEnumerable<T>> inner)
    {
        this.Value = value;
        this.AddRange(inner
            .ToLookup(xs => xs.FirstOrDefault(), xs => xs.Skip(1))
            .Where(xs => xs.Key != null)
            .Select(xs => new Tree<T>(xs.Key, xs)));
    }
    public T Value { get; set; }
}

これは次のように呼び出されます。

var tree = new Tree<string>("Root", lines.Select(x => x.Split('/').Skip(1)));

Tree<T>ただし、これは、クラスを制御する必要があることを意味します。

最初の解決策は、任意のツリー構造を使用できることを意味します。


で動作するバージョンは次のSystem.Windows.Forms.TreeNodeとおりです。

Func<
    IEnumerable<IEnumerable<string>>,
    IEnumerable<TreeNode>>
        buildTreeNode = null;
buildTreeNode = xss =>
    xss
        .ToLookup(xs => xs.FirstOrDefault(), xs => xs.Skip(1))
        .Where(xs => xs.Key != null)
        .Select(xs => new TreeNode(xs.Key, buildTreeNode(xs).ToArray()));
于 2013-08-03T02:22:26.150 に答える