Подсчет объектов вложенного списка при обходе - PullRequest
2 голосов
/ 27 января 2020

Я работаю над проектом в C#, где у меня есть объект со свойствами, один из которых называется Children, который совпадает с родительским объектом. Например:

public class ObjectInformation
{
   public string FullName {get; set;}
   public string FriendlyName {get; set;}
   public List<ObjectInformation> Children {get;}
}

И у меня уже есть метод, который сводит объект root в простой список:

public static IEnumerable<ObjectInformation> Flatten(List<ObjectInformation> objs)
{
   var localCopy = Helpers.General.DeepCopy(objs);
   var finalList = new List<ObjectInformation>();
   foreach(var obj in localCopy)
   {
      if(obj.Children.Count > 0)
      {
         finalList.AddRange(Flatten(obj.Children));
         obj.Children.Clear();
      }

      obj.Parent = null;
      finalList.Add(obj);
   }

   return finalList;
}

Я знаю, что вышеупомянутый метод, вероятно, можно улучшить, но это работает прямо сейчас. Однако сейчас я пытаюсь просмотреть вложенный список и вывести данные с отступом строк в зависимости от уровня вложенности.

Так, например, скажем, у объекта root есть два объекта первый, у которого есть один ребенок, и второй, у которого есть ребенок, у которого также есть ребенок. Я бы хотел, чтобы результат был примерно таким:

FullName of Root Object 1
   FullName of Child 1 of Root Object 1
FullName of Root Object 2
   FullName of Child 1 of Root Object 2
      FullName of Child 1 of Child 1 of Root Object 2

Чтобы сделать отступ, мне нужен какой-то счетчик, чтобы определить, насколько глубоко вложен уровень. Я продолжаю сталкиваться с проблемой, используя рекурсивный метод, потому что при каждом вызове переменная сбрасывается. Я думал, может быть, мне нужно использовать переменную stati c для отслеживания уровня вложенности. Однако проблема, с которой я сталкиваюсь, заключается в том, что при перемещении обратно вверх переменная stati c будет по-прежнему иметь значение самого глубокого уровня, которого она достигла.

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

Любая помощь / предложения, которые вы предоставите, будет принята с благодарностью.

Спасибо

Ответы [ 2 ]

3 голосов
/ 27 января 2020

Я бы порекомендовал метод, который берет объект и печатает каждый с определенным пространством. Рекурсивный вызов будет добавлять x количество пробелов каждый раз, когда вы будете go глубже в объектах.

    public static void Print(this ObjectInformation parent, int spacing = 2)
    {
        Console.WriteLine($"{new string(' ', spacing)}{parent.FullName}");
        foreach (ObjectInformation child in parent.Children)
        {
            child.Print(spacing + 2);
        }
    }
0 голосов
/ 27 января 2020

Я попробовал это же как упражнение и получил рабочий результат.

public void PrintInfoList(IEnumerable<ObjectInformation> list)
    {
        var result = string.Join("\n", list.Select(item => GetPrintedFormat(item)));
        Console.WriteLine(result);
    }

    public string GetPrintedFormat(ObjectInformation info)
    {
        string printedFormat = string.Empty;
        printedFormat = $"Fullname of {info.FriendlyName} - {info.FullName}";
        if (info.Children != null && info.Children.Any())
        {
            childCount++;
            _formatter = $"\n{string.Empty.PadRight(childCount, '\t')}";
            printedFormat += $"{_formatter}{string.Join(_formatter, info.Children.Select(child => GetPrintedFormat(child)))}";
        }
        else
            if (childCount > 0) childCount--;

        return printedFormat;
    }

это проверенное рабочее решение. Дайте мне знать, что вы думаете об этом.

Но я бы тоже хотел проголосовать за самый простой способ Джавада. (Хлопок)

...