Jan*_*ard 4 linq hierarchical-data
是否可以使用.NET的LINQ对层次数据进行求和?
我的数据类如下所示:
class Node
{
public decimal Amount;
public IEnumerable<Node> Children { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
所以我会有一些看起来像这样的数据,但树当然可以任意深入.
var amounts = new Node
{
Amount = 10;
Children = new[]
{
new Node
{
Amount = 20
},
new Node
{
Amount = 30
}
}
};
Run Code Online (Sandbox Code Playgroud)
可以将所有金额相加并通过一个简单的LINQ查询得到结果60?
Jon*_*eet 15
您可以使用更高阶函数来执行此操作:
Func<Node, decimal> summer = null;
summer = node => node.Amount +
(node.Children == null ? 0m : node.Children.Sum(summer));
decimal total = summer(amounts);
Run Code Online (Sandbox Code Playgroud)
请注意,如果您可以确保node.Children永远不会为null,那么summer可以更简单:
summer = node => node.Amount + node.Children.Sum(summer);
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用null合并运算符:
summer = node => node.Amount +
(node.Children ?? Enumerable.Empty<Node>()).Sum(summer);
Run Code Online (Sandbox Code Playgroud)
当然你可以把它放到一个单独的方法中:
static decimal SumNodes(Node node)
{
return node.Amount +
(node.Children ?? Enumerable.Empty<Node>())
.Sum((Func<Node, decimal>)SumNodes);
}
Run Code Online (Sandbox Code Playgroud)
请注意,这里的丑陋是由于方法组转换的模糊性.方法组在类型推断方面没有太多的爱.
然后打电话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);
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定我会将这些称为"简单"的LINQ查询,请注意......