Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在树上汇总值_C#_Linq_Recursion_Tree_Aggregate - Fatal编程技术网

C# 在树上汇总值

C# 在树上汇总值,c#,linq,recursion,tree,aggregate,C#,Linq,Recursion,Tree,Aggregate,我使用树控件查看嵌套(父子)表上的一些层次化项 每个节点都有一个接受名称和值的NameValue格式 但只有叶(最后的节点)具有整数值,父节点的值保留为空(只有它们的名称) 我想对值进行汇总,以便每个父节点都保存其子节点的和,并留下值 我认为需要递归或者LINQ来完成这个任务,但我不知道怎么做 也许一些伪代码会对我有帮助 提前感谢您的帮助 这是未经测试的,但我认为可以设置所有节点的所有值: public void SetNodeValues(Node node) { if (node.N

我使用树控件查看嵌套(父子)表上的一些层次化项

每个节点都有一个接受名称和值的NameValue格式

但只有叶(最后的节点)具有整数值,父节点的值保留为空(只有它们的名称)

我想对值进行汇总,以便每个父节点都保存其子节点的和,并留下值

我认为需要递归或者LINQ来完成这个任务,但我不知道怎么做

也许一些伪代码会对我有帮助


提前感谢您的帮助

这是未经测试的,但我认为可以设置所有节点的所有值:

public void SetNodeValues(Node node)
{
    if (node.Name == String.Empty)
    {
        //If it has no name it is a leaf, which needs no value
        return;
    }
    else
    {
        //Make sure all child-nodes have values
        foreach (var childNode in node.ChildNodes)
        {
            SetNodeValues(childNode);
        }

        //Sum them up and set that as the current node's value
        node.Value = node.ChildNodes.Sum(x => x.Value);
    }
}

这将为您做到这一点:

class Node
{
    public Node()
    {
        Children = new List<Node>();
    }

    public IEnumerable<Node> GetSubTree()
    {
        return Children.SelectMany(c => c.GetSubTree()).Concat(new[] { this });
    }

    public List<Node> Children { get; set; }
    public string Value { get; set; }
}

class Tree
{
    public Tree()
    {
        Root = new Node();
    }

    public IEnumerable<Node> GetAllNodes()
    {
        return Root.Children.SelectMany(root => root.GetSubTree()); 
    }

    Node Root { get; set; }

    //This is the Property you want:
    public int GetValuesSum
    {
        get
        {
            return GetAllNodes().Where(node => !string.IsNullOrEmpty(node.Value)).Sum(node => Convert.ToInt32(node.Value));
        }
    }
}
类节点
{
公共节点()
{
Children=新列表();
}
公共IEnumerable GetSubTree()
{
返回Children.SelectMany(c=>c.GetSubTree()).Concat(new[]{this});
}
公共列表子项{get;set;}
公共字符串值{get;set;}
}
类树
{
公树()
{
根=新节点();
}
公共IEnumerable GetAllNodes()
{
返回Root.Children.SelectMany(Root=>Root.GetSubTree());
}
节点根{get;set;}
//这是您想要的属性:
公共int GetValuesSam
{
得到
{
返回GetAllNodes().Where(node=>!string.IsNullOrEmpty(node.Value)).Sum(node=>Convert.ToInt32(node.Value));
}
}
}

参考资料:

那不是一棵树,它是一片森林--@H.B我把它改成了一棵树;)哈哈,很好,但我仍然想知道这是否适用于OP,目标数据结构在描述中有点不明显。他/她还想设置分支节点的值,而不仅仅是求和。@H.B.正如他所说,只有叶节点有值,其他节点留空。所以您可以看到,这段代码只获取叶节点的和。测试和工作坦克法辛为了你的注意,我正在检查你的解决方案,似乎它的工作。但是你可以通过一个递归方法来完成这个任务吗?例如,所有的父节点都会自动填充,这样我就可以将它绑定到DataGridView?非常感谢。你的解决方案很有帮助,它解决了我的问题。谢谢,我知道它应该能用,现在我不辞辛劳地免费测试它。