Reputation: 476
I am working on a project in C# where I have an object with properties, one of which is called Children
which is the same as the parent object. For example:
public class ObjectInformation
{
public string FullName {get; set;}
public string FriendlyName {get; set;}
public List<ObjectInformation> Children {get;}
}
And I already have a method which flattens a root object into a simple list:
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;
}
I know the above method could probably be improved, but it works right now. However, what I'm trying to do now is traverse the nested list and output the data, while indenting lines depending on the nesting level.
So, as an example, say the root object has two objects, the first one which has one child, and the second which has a child, which also has a child. I would want the output to be something like this:
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
To do the indenting, I need some kind of counter to determine how deep the level is nested. I keep running into an issue using a recursive method though because on each call, the variable is reset. I was thinking, maybe I need to use a static variable to track the nesting level. The issue I see with that though is that as it travels back up, the static variable will still have the value of the deepest level its reached.
I'm kind of at a lost of how to proceed with this, albeit I'm sure it is probably a simple solution I just can't picture at the moment; I generally don't use/need recursion so I don't have a lot of experience actually using it.
Any help/suggestions you an provide would be greatly apprecated.
Thank You
Upvotes: 2
Views: 538
Reputation: 406
I tried this same as an exercise and got a working result.
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;
}
this is tested working solution. Let me know what you think of this.
But i like to vote @Jawad's simplest way too. (clap)
Upvotes: 0
Reputation: 11364
I would recommend a method that takes the object and prints each with a defined space. Recursive call would add x
amount of spaces each time you would go in deeper within the objects.
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);
}
}
Upvotes: 3