Saket Kumar
Saket Kumar

Reputation: 4835

How to get total count of children of a class containing Dictionary of same type?

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 Nodes 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

Answers (2)

TomT
TomT

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

BartoszKP
BartoszKP

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

Related Questions