I have two methods to return a dynamic hierarchical structure from a flat List. The first works great using the recursive method here: (ID/ParentID) list to Hierarchical list.
I’m now trying to do the same thing except this time show only those categories and reports which have a saved report output. I’m not sure where to start as everything I find is building from root down and I need to go from the bottom up.
I get something like this now in my first method:
Category 1
|_Sub Category 1
|_Report 1
|_Report 2
|_Saved Output
Category 2
|_Sub Category 2
| |_Report 3
| |_Report 4
|_Sub Category 3
|_Report 5
|_Report 6
|_Saved Output
Category 3
|_Sub Category 4
|_Report 7
What I want in my second method is this:
Category 1
|_Sub Category 1
|_Report 2
|_Saved Output
Category 2
|_Sub Category 3
|_Report 6
|_Saved Output
Here’s my basic test structure:
class Flat
{
public int id { get; set; }
public int parentId { get; set; }
public string name { get; set; }
public bool isOutput { get; set; }
public Flat(int i, int pid, string n, bool o)
{
this.id = i;
this.parentId = pid;
this.name = n;
this.isOutput = o;
}
}
class MyClass
{
public int id { get; set; }
public int parentId { get; set; }
public string name { get; set; }
public bool isOutput { get; set; }
public List<MyClass> children { get; set; }
public MyClass()
{
this.children = new List<MyClass>();
}
}
List<Flat> items = new List<Flat>()
{
new Flat(1,0,"Category 1",false),
new Flat(4,1,"Sub Category 1",false),
new Flat(8,4,"Report 1",false),
new Flat(9,4,"Report 2",false),
new Flat(15,9,"Saved Output",true),
new Flat(2,0,"Category 2",false),
new Flat(5,2,"Sub Category 2",false),
new Flat(10,5,"Report 3",false),
new Flat(11,5,"Report 4",false),
new Flat(6,2,"Sub Category 3",false),
new Flat(12,6,"Report 5",false),
new Flat(13,6,"Report 6",false),
new Flat(16,13,"Saved Output",true),
new Flat(3,0,"Category 3",false),
new Flat(7,3,"Sub Category 4",false),
new Flat(14,7,"Report 7",false)
};
To build from the bottom up, you need to start with all the leaf nodes that are valid (
output == true), and then work upwards through all parent nodes until you reach the root. Here’s one method that should work:This is short and quick, and should work well for small, simple trees, but it is not the most efficient method because of processing the same nodes over and over again. A slightly more complex, but better method, would be to walk up the parent tree for each item:
If this is still not efficient enough, you can get a little more performance by storing references to the parent node in each
Flatinstance, so that the parent can be directly referenced inO(1)without having to look it up using a call toSingle, which has efficiencyO(n).