简体   繁体   English

如何使用递归方法在树结构中创建多行字符串?

[英]How to create a multi-line string in a tree structure using a recursive method?

I have this model: 我有这个模型:

public class TreeModel
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public string Name { get; set; }

    public static List<TreeModel> GetData()
    {
        var list = new List<TreeModel>()
        {
            new TreeModel() {Id = 1,ParentId = null,Name = "Name1"},
              new TreeModel() {Id = 2,ParentId = null,Name = "Name2"},
                new TreeModel() {Id = 3,ParentId = null,Name = "Name3"},
                  new TreeModel() {Id = 4,ParentId = 1,Name = "Name4"},
                    new TreeModel() {Id = 5,ParentId = 1,Name = "Name5"},
                      new TreeModel() {Id = 6,ParentId = 4,Name = "Name6"},
                        new TreeModel() {Id = 7,ParentId = 6,Name = "Name7"},
        };

        return list;
    }

    public static string ShowTree(List<TreeModel> source)
    {
        var text = "";
        foreach (var item in source)
        {
            if (item.ParentId != null) continue;
            text += item.Name + "\n";
            var childs = source.Where(x => x.ParentId == item.Id).ToList();
            if (!childs.Any()) continue;
            {
                foreach (var child in childs)
                {
                    text += "  " + child.Name + "\n"; //2 spaces
                    var childs2 = source.Where(x => x.ParentId == child.Id).ToList();
                    if (!childs2.Any()) continue;
                    {
                        foreach (var child2 in childs2)
                        {
                            text += "    " + child2.Name + "\n"; //4 spaces
                            var childs3 = source.Where(x => x.ParentId == child2.Id).ToList();
                            if (!childs3.Any()) continue;
                            foreach (var child3 in childs3)
                            {
                                text += "      " + child3.Name + "\n"; //6 spaces
                            }
                        }
                    }
                }
            }
        }
        return text;
    }

}

with my method ShowTree , I am able to get this: 使用我的方法ShowTree ,我可以获得:

Name1
  Name4
    Name6
      Name7
  Name5
Name2
Name3

Can someone help me transform this method in recursive one, in order to use it with a larger data-set. 有人可以帮我递归地转换此方法,以便将其用于更大的数据集。

You need to use a recursive function : 您需要使用递归函数:

public static string ShowTree(List<TreeModel> source)
{
    var buffer = new StringBuilder();
    foreach (var item in source.Where(x => !x.ParentId.HasValue))
    {
        WriteTree(buffer, source, item);
    }

    return buffer.ToString();
}
private static void WriteTree(StringBuilder buffer, List<TreeModel> source, TreeModel item, int level = 0)
{
    buffer.AppendLine(new string('\t', level) + item.Name);
    foreach (var child in source.Where(x => x.ParentId == item.Id))
    {
        WriteTree(buffer, source, child, level + 1);
    }
}

Just call the ShowTree method and you will get your formatted data. 只需调用ShowTree方法,您将获得格式化的数据。

Edit: Using StringBuilder because of better performance: 编辑:由于更好的性能,使用StringBuilder:

public static string ShowTree(List<TreeModel> source) {
    var empty = new StringBuilder();
    source.Where(s => s.ParentId == null).ToList().ForEach(s => ShowNode(source, s, empty));
    return empty.ToString();
}

private static void ShowNode(List<TreeModel> source, TreeModel model, StringBuilder text, int depth = 0) {
    text.Append(Enumerable.Repeat(" ", depth++).Aggregate("", (s, s1) => s + s1) + model.Name + "\n");

    source.ForEach(m => {
        if (model.Id == m.ParentId) ShowNode(source, m, text, depth);
    });
}

Try following code 尝试以下代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ProgrammingBasics
{
    class Program
    {
        static void Main(string[] args)
        {
            TreeModel model = new TreeModel();
            string text = model.ShowTree();
            Console.WriteLine(text);
            Console.ReadLine();
        }
    }
    public class TreeModel
    {
        public int Id { get; set; }
        public int? ParentId { get; set; }
        public string Name { get; set; }

        public static List<TreeModel> GetData()
        {
            var list = new List<TreeModel>()
            {
                new TreeModel() {Id = 1,ParentId = null,Name = "Name1"},
                new TreeModel() {Id = 2,ParentId = null,Name = "Name2"},
                new TreeModel() {Id = 3,ParentId = null,Name = "Name3"},
                new TreeModel() {Id = 4,ParentId = 1,Name = "Name4"},
                new TreeModel() {Id = 5,ParentId = 1,Name = "Name5"},
                new TreeModel() {Id = 6,ParentId = 4,Name = "Name6"},
                new TreeModel() {Id = 7,ParentId = 6,Name = "Name7"},
            };

            return list;
        }
        public string ShowTree()
        {
            int level = 0;
            return ShowTreeRecursive(GetData(), level, null); 
        }

        public static string ShowTreeRecursive(List<TreeModel> source, int level, int? ParentId)
        {
            string text = "";
            foreach(var node in source.Where(x => x.ParentId == ParentId))
            {
                text += string.Format("{0} {1}\n", new string(' ', 3 * level), node.Name);
                text += ShowTreeRecursive(source, level + 1, node.Id);
            }
            return text;
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM