Reputation: 4425
In my Azure table I have a tree like structure. What I am trying to achieve is to get a list of data like this
var data = [{
item1 : {
name : "",
children : [] // list of children, if any children is a parent of other items get those
}
}]
I have written this code
List<dynamic> test = new List<dynamic>();
DisplayTree(NewMassType.GetAll().Where(e => e.ParentId == null), test);
public void DisplayTree(IEnumerable<NewMassType> elements, List<dynamic> test)
{
foreach (var element in elements)
{
test.Add(new
{
name = element.Name
});
var children = NewMassType.GetAll().Where(e => e.ParentId == element.Id);
if (children.Count() > 0)
{
DisplayTree(children,test);
}
}
}
It gives me a flat list out. Looking forward for suggestions.
Upvotes: 2
Views: 4993
Reputation: 37533
The reason it gives you a flat list is because you're passing in the top level collection each time.
DisplayTree(children,test);
What this does is it just appends the children to the end of the list. What you really need is an alternate method that specifically populates the children rather than the top level.
List<dynamic> test = NewMassType.GetAll().Where(e => e.ParentId == null);
foreach (var element in test)
{
PopulateChildren(element);
}
// Somewhere down the line have a method
public void PopulateChildren(dynamic element)
{
var children = NewMassType.GetAll().Where(e => e.ParentId == element.Id);
element.children = children;
foreach (var child in element.children)
{
PopulateChildren(child);
}
}
You have to make sure each parent/child assignment happens at the right place as its done otherwise you'll keep getting a flat list.
Note: I've changed some of the data types here to use dynamic as you've done, but I really recommend creating an enforced type to hold the structure you want rather than relying on anonymous types.
Upvotes: 1
Reputation: 726519
In order to build a hierarchy you need to store the results inside hierarchy, not inside a flat list. Your recursive approach needs to be reworked:
static List<dynamic> DisplayTree(IEnumerable<NewMassType> elements) {
var res = new List<dynamic>();
foreach (var element in elements) {
var children = DisplayTree(NewMassType.GetAll().Where(e => e.ParentId == element.Id)).ToArray();
if (children.Length != 0) {
res.Add(new {
name = element.Name
, children = children
})
} else {
res.Add(new {
name = element.Name
})
}
}
return res;
}
The key difference between this code and your code is that each recursive invocation produces a separate list, which is added to objects of the anonymous type when it is not empty.
Upvotes: 3