Logic for creating a tree like representation - c#

I have an requirement to show a binary tree like structure on the web page that will
be used to represent parent-child relation. Unlike binary tree, this tree can have multiple child nodes
and the childs can have further children and this process will continue until no child left of their parent.
So, I am pretty much confused on how should my data-model should be and my thinking is not going beyond this one
public class Parent
{
public string parentName {get;set;} // As their will be one start for this tree, I will have one parent node that will show the parent
public List<string> child {get;set;} // As the parent can have multiple children, I can have a list of string
}
But the question is that the child can also act as parent as they can also have children. How should I
implement such structure.
Thanks

A string can't have child elements of its own, so it's not a good representation.
A simple way is to make the child elements simply a List of the same type of element as the parent. Let's call them all Node instead:
public class Node
{
public string Name { get; set; }
public List<Node> ChildNodes { get; set; }
}

Related

Find orphaned elements within a hierarchy

I am struggling to find a good solution for this. It's fairly straight forward to find the orphaned elements, but the trouble is storing them in such a way that they can easily be merged back into the hierarchy at a later point.
I the following abstract class that has multiple implementations:
public abstract class FilterElement
{
public abstract string ID { get; }
public abstract IEnumerable<FilterElement> Children { get; set; }
public FilterElement Parent { get; set; }
}
I have two hierarchies of FilterElement - the "master" (i.e. the main structure), and the "filters". The filters point at elements in the master - however, if these master elements do not exist, I wish to create a third structure, the "orphans".
I'm struggling to do this. While it's easy to identify the orphaned elements, I don't know how to store them effectively. This is the current solution:
Note: "GetFlatKey" returns a unique key for the element based on it's parents & children, and "RecursiveSelect" effectively flattens the hierarchy:
private IEnumerable<FilterElement> GetOrphanedFilterElements
(IEnumerable<FilterElement> filters,
IEnumerable<IFilterFileViewModel> visibleList)
{
var flattenedMasterList = visibleList.Cast<IFilterViewModel>()
.RecursiveSelect(f => f.Children)
.Select(x => x.GetFlatKey).ToList();
var orphanedFilterFiles = new List<FilterElement>();
foreach (var f in filters.RecursiveSelect(f => f.Children))
{
// Remove non orphaned files.
if (!flattenedMasterList.Contains(f.GetFlatKey))
{
orphanedFilterFiles.Add((f));
}
}
return orphanedFilterFiles;
}
The problem with this is that the elements in the orphanedFilterFiles list contain references to other elements - e.g. An orphan will have a parent, which may have non-orphaned Children. This makes it difficult to merge back into the final hierarchy, which is the main issue.
Can anyone help me find a better solution, or just tell me what I'm doing wrong?

Performant editing and traversing of a hierachical list

I'm having trouble editing fields/properties in a hierarchical list with the help of a second lookup list. Everything I try looks like a mess and is hard to maintain. Are binary search trees my friend? How would I apply them? Flattening my hierarchical structure doesn't work as I need the hierarchy, just filtered.
public class Filter
{
public string Name {get;set;}
public bool IsActive {get;set;}
public bool IsDisplayed {get;set;}
public string List<Filter> Filters {get;set}
}
public List<string> ActiveFilters {"Green", "LighterYellow", "Red", "Meep")};
My base filters basically look like this:
Colors
Green
Yellow
LightYellow
LighterYellow
OrangishYellow
Red
DarkRed
Sounds
Meep
Moop
Maap
Now I'm trying to set some of these filters to active. But of course the parents of children who are in the ActiveFilters need to be displayed (IsDisplayed) otherwise you wouldn't be able to see the child items.
In the end I want the hierarchy to look like this (based on applying the ActiveFilters, bold indicates IsActive, italic IsDisplayed):
Colors
Green
Yellow
LightYellow
LighterYellow
Red
Sounds
Meep
I have been trying to recursively loop through the hierarchical list, but I don't know how to set the parents to IsDisplayed (as I would have to "go back up"). When looping the other way through the ActiveFilters I don't want to iterate over the whole filter list for each active filter performance wise.
I would do something like this:
First, add a Parent property to Filter
public class Filter
{
public string Name {get;set;}
public bool IsActive {get;set;}
public bool IsDisplayed {get;set;}
public string List<Filter> Filters {get;set}
// Parent
public Filter Parent {get;set;}
}
In your initialization code for the hierarchy, make sure you populate Parent correctly. (I don't know what your code looks like, so I'll leave that part to you.)
Next, in your code that highlights the active filters, do something like:
var parent = activeFilter.Parent;
while (parent != null)
{
parent.IsDisplayed = true;
parent = parent.Parent;
}

Removing Tree Branches with C#

I have a List<Leaf> named items in C#. A Leaf has the following properties:
public class Leaf
{
public int ID { get; set; }
public int ParentID { get; set; }
public bool IsFlagged { get; set; }
}
If a Leaf has the IsFlagged property set then I need to remove it from the collection of items. In addition, I need to remove all of that Leaf entity's children. I'm trying to figure out the most elegant way to write this code. Currently, I have a loop within a loop, but it seems sloppy.
Does anyone know of an elegant way to do this?
Perhaps:
void RemoveItAndChildren(Leaf leaf)
{
foreach (Leaf item in items)
if (item.ParentID == leaf.ID)
RemoveItAndChildren(item);
items.Remove(leaf);
}
And use so:
foreach (Leaf leaf in items)
if (leaf.IsFlagged)
RemoveItAndChildren(leaf);
Note that, as in a comment above, something like the following might be more appropriate:
public class Leaf2
{
List<Leaf2> Children;
bool IsFlagged { get; set; }
}
Most reasonable (and probably "the most elegant") way of dealing with tree is to store it as a tree, not an array/list. In this case you'll not need to deal with walking elements to try to find all children.
Note that depending on your actual requirements tree may not be best data structure, but for removing node with all children nodes it would be hard to beat regular tree.

Linq - How to get all children

I have a Type MenuItem that has one-to-many relationship with itself through Children property.
public class MenuItem
{
//Some properties
public IList<MenuItem> Children{get; set;}
}
Now Is there any way in Linq-To-NH to fetch all children until leaf level (not just direct children) for a node.
They seem to have a way to do it using join fetch:
http://ayende.com/blog/4151/nhibernate-tips-tricks-efficiently-selecting-a-tree
http://nhibernate.hibernatingrhinos.com/16/how-to-map-a-tree-in-nhibernate

Objects containing list of same object type

Is there anything wrong with defining something like this:
class ObjectA
{
property a;
property b;
List <ObjectA> c;
...
}
No, and because the answer needs at least 30 characters, I'll add that this is a common pattern.
Since you included the oop tag, though, I'll add that this pattern gives a lot of control to the outside world. If c is a list of children, for example, you're giving everyone who has access to an instance of ObjectA the ability to add, delete, or replace its children.
A tighter approach would be to use some sort of read-only type (perhaps implementing IList<ObjectA>) to expose the children.
EDIT
Note that the following still allows others to modify your list:
class ObjectA
{
property a;
property b;
List <ObjectA> c;
...
public List<ObjectA> Children { get { return c; } }
}
The absence of a setter only prevents outsiders from replacing the list object.
Nope. That's perfectly acceptable. Tree structures do this.
It is perfectly valid. For example, you would have to do something like this to build a tree data structure (parent node contains a list of child nodes).
i have to ask if your question is about putting a List< > in there, or if it is about putting a List< ObjectA > inside of ObjectA. and the answer to both questions is "Yes"!
the thing to keep in mind is that by default, the access is private. if you want other classes to use this list, then you need to add a few things to your class...
class ObjectA
{
property a;
property b;
List <ObjectA> c;
// allow access, but not assignment
// you can still modify the list from outside, you just cant
// assign a new list from outside the class
public List<ObjectA> somePropertyName{ get { return this.c;}}
// same as above, only allow derived child classes to set the list
public List<ObjectA> somePropertyName{ get { return this.c;}
protected set { this.c = value;} }
// allow all access
public List<ObjectA> somePropertyName{ get { return this.c;}
set { this.c = value;} }
}
No. This is valid. Many structures uses this graph like pattern.
If you eg have a base collection class
namespace MiniGraphLibrary
{
public class GraphCollection
{
public Node Root { set; get; }
public Node FindChild(Node root)
{
throw new NotImplementedException();
}
public Node InsertNode(Node root, Node nodeToBeInserted)
{
throw new NotImplementedException();
}
}
}
Then you can have the node act like this:
namespace MiniGraphLibrary
{
public class Node
{
private string _info;
private List<Node> _children = new List<Node>();
public Node(Node parent, string info)
{
this._info = info;
this.Parent = parent;
}
public Node Parent { get; set; }
public void AddChild(Node node)
{
if (!this.DoesNodeContainChild(node))
{
node.Parent = this;
_children.Add(node);
}
}
public bool DoesNodeContainChild(Node child)
{
return _children.Contains(child);
}
}
}
Note that this is something I wrote in 2 minutes, and it is problery not good in production, but the 2 main things is that you have a parent node and many children. When you add a child node to a given node, then you make sure that it has its parent node set. Here I first check if the child is allready in the children list before connection the two.
You could make some changes to the code, and make sure that if a child is removed an parent lists that it is allready connected to. I have not done this there.
I have made this to illustrate how it could be used. And it is used many places. Fx clustered indexes in MSSQL uses some sort of this tree like representation. But I am NOT an expert on this subject, so correct me if I am wrong.
I have not implemented the two classes in the GraphCollection class. The downside of my little example is that you if you are going to implement the Find method, then you have to go through the whole graph. You could make a binary tree that only has two children:
namespace MiniTreeLibrary
{
public class SimpleNode
{
private string _info;
private SimpleNode _left;
private SimpleNode _right;
private SimpleNode _parent;
public SimpleNode(Node parent, string info)
{
this._info = info;
this.Parent = parent;
}
public Node Parent { get; private set; }
}
}
I have omitted the insertion of the right and left. Now with this binary tree you could do some pretty darn fast searching, if you wanted!! But that is another discossion.
There is many rules when it comes trees and graphs, and my graph is even a real graph. But I have put these examples here so you can see that it is used alot!! If you want to go more into linear and other data structures, then see this serie of articles. Part 3, 4 and 5 they talks alot more about trees and graphs.

Categories