Вопрос:

Как создать многострочную строку в древовидной структуре с помощью рекурсивного метода?

c#

59 просмотра

3 ответа

1553 Репутация автора

У меня есть эта модель:

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

}

с моим методом ShowTreeя могу получить это:

Name1
  Name4
    Name6
      Name7
  Name5
Name2
Name3

Может кто-нибудь помочь мне преобразовать этот метод в рекурсивный, чтобы использовать его с большим набором данных.

Автор: Lucian Bumb Источник Размещён: 22.08.2016 08:32

Ответы (3)


1 плюс

461 Репутация автора

Решение

Просто вызовите ShowTreeметод, и вы получите отформатированные данные.

Изменить: Использование 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);
    });
}
Автор: whymatter Размещён: 22.08.2016 09:12

2 плюса

12254 Репутация автора

Вам нужно использовать рекурсивную функцию:

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);
    }
}
Автор: Xiaoy312 Размещён: 22.08.2016 09:12

1 плюс

21358 Репутация автора

Попробуйте следующий код

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

}
Автор: jdweng Размещён: 22.08.2016 09:34
Вопросы из категории :
32x32