linq - 使用 LINQ 的分层数据总和?

标签 linq hierarchical-data

是否可以使用 .NET 的 LINQ 对分层数据求和?

我的数据类如下所示:

class Node
{
    public decimal Amount;
    public IEnumerable<Node> Children { get; set; }
}

所以我会有一些数据看起来像这样,但树当然可以任意深。
var amounts = new Node
{
    Amount = 10;
    Children = new[]
    {
        new Node
        {
            Amount = 20
        },
        new Node
        {
            Amount = 30
        }
    }
};

可以通过一个简单的 LINQ 查询将所有金额相加并获得结果 60?

最佳答案

您可以使用更高阶的函数来做到这一点:

Func<Node, decimal> summer = null;
summer = node => node.Amount + 
                 (node.Children == null ? 0m : node.Children.Sum(summer));
decimal total = summer(amounts);

请注意,如果您可以确保 node.Children 永远不会为 null,则 summer 可以更简单:
summer = node => node.Amount + node.Children.Sum(summer);

或者,您可以使用 null 合并运算符:
summer = node => node.Amount + 
                 (node.Children ?? Enumerable.Empty<Node>()).Sum(summer);

当然,您可以将其放入单独的方法中:
static decimal SumNodes(Node node)
{
    return node.Amount + 
        (node.Children ?? Enumerable.Empty<Node>())
            .Sum((Func<Node, decimal>)SumNodes);
}

请注意,这里的丑陋是由于方法组转换中的含糊不清。方法组在类型推断中并不受欢迎。

然后调用SumNodes(amount) .很多选择:)

第一种形式的完整示例:
using System;
using System.Collections.Generic;
using System.Linq;

class Node
{
    public decimal Amount;
    public IEnumerable<Node> Children { get; set; }
}

public class Test
{
    static void Main()
    {
        var amounts = new Node {
            Amount = 10, Children = new[] {
                new Node { Amount = 20 },
                new Node { Amount = 30 }
            }
        };

        Func<Node, decimal> summer = null;
        summer = node => node.Amount + 
            (node.Children == null ? 0m : node.Children.Sum(summer));

        decimal total = summer(amounts);

        Console.WriteLine(total);
    }
}

我不确定我是否会将这些中的任何一个称为“简单”LINQ 查询,请注意……

关于linq - 使用 LINQ 的分层数据总和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/969174/

相关文章:

c# - 使用 linq 查询 ASP.NET 表单对象

c# - 如何区分不同的值(value)观?

mysql - SQL树遍历

python - 将分层关键字与文档相匹配

mysql - 在 MySQL/PHP 中实现嵌套顺序集

c# - LINQ 获取所有继承人的 child

c# - LINQ 查询基于列表的子字符串进行过滤

C# LINQ .Any 不适用于 DocumentDb CreateDocumentQuery

SQL 获取所有类别和所有子类别

php - 我应该在SQL或PHP中使用循环吗?