Тестовые данные для построения древовидного меню с использованием рекурсивного метода?

#c# #recursion

#c# #рекурсия

Вопрос:

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

 private MenuItem _menuItem;
private int _start = 1;
private const int Stop = 5;

public void BuildMenu()
{
    var numberOfChildren = new Random((int) DateTime.Now.Ticks).Next(3, 40);
    AutoMapper.Mapper.CreateMap<MenuItem, MenuItemDto>().ConvertUsing<MenuItemConverter>();
    _menuItem = new MenuItem() {Id = Guid.NewGuid(), Name = "Main Menu"};
    _menuItem.ChildMenuItems = BuildChildItems(_menuItem, numberOfChildren);

    var menuDto = AutoMapper.Mapper.Map<MenuItem, MenuItemDto>(_menuItem);
}

public ICollection<MenuItem> BuildChildItems(MenuItem parentMenuItem, int numberOfChildren)
{
    var childItems = new Collection<MenuItem>();

    _start  = 1;

    for (var i = 0; i <= numberOfChildren; i  )
    {
        var childItem = new MenuItem()
                            {
                                Id = Guid.NewGuid(),
                                ParentItemId = parentMenuItem.Id,
                                Parentitem = parentMenuItem,
                                Name = "Child Menu Item  "   DateTime.Now
                            };

        if (_start != Stop)
        {
            childItem.ChildMenuItems = BuildChildItems(childItem, numberOfChildren);
        }

        childItems.Add(childItem);
    }

    return childItems;
}

public class MenuItem
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public Guid? ParentItemId { get; set; }
    public MenuItem Parentitem { get; set; }
    public ICollection<MenuItem> ChildMenuItems { get; set; }
}
  

Пока это работает, вы заметите переменные _start и Stop . Я вставил их, поэтому я не получаю stackoverflow, но, очевидно, именно поэтому я получаю только 1-й уровень каждого из заполненных дочерних элементов. Я полагаю, мне нужно будет отслеживать, на каком уровне я нахожусь, но не уверен, как это отслеживать. Не уверен, почему я сегодня рисую пробел….

Ответ №1:

Это дает представление, а не фактически рассматривает вашу конкретную объектную модель! Есть int, который представляет количество уровней, на которые вы хотите перейти. Отправьте это в метод, уменьшайте его при каждой рекурсии, пока оно не станет равным нулю.

 public void BuildChildItems(MenuItem parentMenuItem, int numberOfChildren, int level)
{
  if(level == 0) return;

  var results_for_this_level = create_results_for_this_level();
  parentMenuItem.Add(results_for_this_level);


  foreach(sibling in results_for_this_level)
  {
     BuildChildItems(sibling, numberofChildren, level-1) //note the decrement of level here
  } 
    }