如何获取包含相同类型字典的类的子项总数?

时间:2014-11-11 10:09:12

标签: linq c#-4.0

我有一个'Node'类,如下所示:

public class Node
{
public readonly IDictionary<string, Node> _nodes =
new Dictionary<string, Node>();

public string Path { get; set; }            
}

我希望获得上述类对象的_nodes的总子数。可以有任何深度。让我们假设我创建一个对象:

Node obj = new Node();

迭代后,我希望在所有深度级别得到Node的总数。我尝试了以下但不起作用:

foreach (var item in obj._nodes) 
{ 
count += item.Value._nodes.SelectMany(list => list.Value._nodes).Distinct().Count(); 
}

2 个答案:

答案 0 :(得分:1)

此问题的典型解决方案是创建recursive method,如下所示:

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部分用于计算节点本身。

我省略了对Distinct功能的调用。它可能不会起作用,因为您的节点没有覆盖EqualsGetHashCode方法。

答案 1 :(得分:1)

你所拥有的是一棵节点树。您需要展平它,然后您可以轻松地计算节点。这是一个非常好的扩展方法,我在很久以前的地方搜索过:

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);
}

如果你有这个,其余的很容易:

var count = new [] {obj}.Flatten(x => x._nodes.Values).Distinct().Count();

您可能希望在节点上覆盖Equals和GetHashCode,以使Distinct()按预期工作。