How to Trim Hierarchical Data Without Breaking It
We’ve got a Hierarchical list of nodes that make up a tree where users can expand/collapse and select different nodes. The nodes however come in two distinct types, and I needed to come up with a way of trimming the list on the fly to display one type or another. I came up with the following code.
private static List<Node> FilterList(List<Node> list, Utilities.TypeRequired type)
{
List<Node> returnList = new List<Node>();
// Go through each node of the full list and run the FilterNode recursive method
foreach (Node item in list)
returnList.AddRange(FilterNode(item, type));
return returnList;
}
private static List<Node> FilterNode(Node item, Utilities.TypeRequired type)
{
// Prep return list
List<Node> list = new List<Node>();
// call this same method on each of the children of this node, store in list
foreach (var child in item.Children)
list.AddRange(FilterNode(child, type));
if (item.TypeId == (int)type)
{
// if the node is of the correct type, set it's current children to the
// results from above and return the item within a list
item.Children.Clear();
item.Children.AddRange(list);
return new List<Node>() { item };
}
else
// if not, just return the children without the parent
return list;
}
The FilterList() method accepts a list of nodes, this is considered to be the first level of children under the root node (in this case there is no root node). It also takes an object that I’ve called TypeRequired, really it can be any kind of data you’d like to use to evaluate the differences between one node and another. The method self-references on the children of the current node and so works through the whole tree.
The real trick here is that in cases where a parent node is not a match to the desired type, the children are promoted to it’s place in the hierarchy before the parent is removed. This way qualifying children stay in the list organized in the proper fashion.