Как перебрать древовидную структуру с логи c на том, где остановиться - PullRequest
0 голосов
/ 11 марта 2020

Для данного класса;

public class TreeNode
{
    public string nodeType;
    public string nodeName;
    public List<TreeNode> Children;
}

, экземпляром которого является:

var tree = new TreeNode()
            {
                nodeName = "Fred",
                Children = new List<TreeNode>()
                {
                    new TreeNode() { nodeName = "James" },
                    new TreeNode()
                    {
                        nodeName = "Lucy",
                        Children = new List<TreeNode>()
                        {
                            new TreeNode() { nodeName = "James",
                                Children = new List<TreeNode>()
                                {
                                    new TreeNode() { nodeName = "Bob" },
                                    new TreeNode() { nodeName = "Kevin" },
                                } },
                            new TreeNode() { nodeName = "Kevin" }
                        }
                    }

                }
             };

Как бы я go отфильтровал список по "Джеймсу" и возвратил дерево как коллекцию, как ;

Fred - James
Fred - Lucy - James

Смысл в том, что ему не нужно включать какой-либо дочерний узел в критерии фильтра. Я хотел бы использовать linq, если это возможно, но не уверен, что это возможно.

Спасибо

1 Ответ

1 голос
/ 11 марта 2020

Вот вам go:

IEnumerable<TreeNode[]> Flatten(TreeNode node) =>
    (node.Children ?? new List<TreeNode>())
        .SelectMany(child => Flatten(child))
        .Select(nodes => nodes.StartWith(node).ToArray())
        .StartWith(new[] { node });

IEnumerable<TreeNode[]> results =
    Flatten(tree)
        .Where(nodes => nodes.Last().nodeName == "James");

string text =
    String.Join(
        Environment.NewLine,
        results.Select(nodes =>
            String.Join(
                " - ",
                nodes.Select(node => node.nodeName))));

Это дает мне:

Fred - James
Fred - Lucy - James

Вот версия, не требующая пакета Microsoft System.Interactive NuGet:

IEnumerable<TreeNode[]> Flatten(TreeNode node) =>
    new[] { new[] { node } }
        .Concat(
            (node.Children ?? new List<TreeNode>())
                .SelectMany(child => Flatten(child))
                .Select(nodes => new[] { node }.Concat(nodes).ToArray()));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...