Reputation: 4835
I have a 'Node' class as follows:
public class Node
{
public readonly IDictionary<string, Node> _nodes =
new Dictionary<string, Node>();
public string Path { get; set; }
}
I want to get the total child count of _nodes
of object of the above class. There can be any level of depths. Let us suppose i create an object as:
Node obj = new Node();
After iterating, i wish to get total no of Node
s at all levels of depth. I tried the following but it is not working:
foreach (var item in obj._nodes)
{
count += item.Value._nodes.SelectMany(list => list.Value._nodes).Distinct().Count();
}
Upvotes: 0
Views: 76
Reputation: 971
What you have there is a tree of nodes. You need to flatten this and then you could count the nodes easily. This is a very nice extension method I googled somewhere ages ago:
public static IEnumerable<T> Flatten<T>(
this IEnumerable<T> e,
Func<T, IEnumerable<T>> f)
{
return e.SelectMany(c => f(c).Flatten(f)).Concat(e);
}
When you have that, the rest is easy:
var count = new [] {obj}.Flatten(x => x._nodes.Values).Distinct().Count();
You may want to override Equals and GetHashCode on Node to make Distinct() work as expected.
Upvotes: 1
Reputation: 35891
A typical solution to this problem is to create a recursive method, like this:
public class Node
{
public readonly IDictionary<string, Node> _nodes
= new Dictionary<string, Node>();
public int GetTotalChildrenCount()
{
return _nodes.Values.Sum(n => n.GetTotalChildrenCount() + 1);
}
}
+ 1
part is used to count a node itself, apart from the number of its children.
I've omitted the call to the Distinct
function. It will probably won't work, as your node doesn't have Equals
and GetHashCode
method overridden.
Upvotes: 2