从 C# 中的列表创建树,并进行分组
Create a tree from a list in C#, with grouping
我有这个class:
class Foo
{
Category1 Cat1;
Category2 Cat2;
Category3 Cat3;
decimal Weight;
}
每个Categoryi
都有一个string Name
属性
所以 Foos
的列表可能如下所示:
Cat1 Cat2 Cat3 Weight
--------------------------------
AP SG X 10
AP SG S 5
AP J X 5
AP AR S 10
NE R L 7
...
我想从列表中创建一棵树。即:
一个节点列表,作为一个节点:
class Node
{
string Name;
decimal Weight;
List<Node> Children;
}
使用此层次结构顺序:Category1、Category2、Category3,树将如下所示:
|--AP (Weight: 30)
| |
| |--SG (Weight: 15)
| | |-- X (Weight: 10)
| | |-- S (Weight: 5)
| |
| |--J (Weight: 5)
| | |-- X (Weight: 5)
| |
| |--AR (Weight: 10)
| |-- S (Weight: 10)
|
|--NE (Weight: 7)
|
|-- R (Weight: 7)
|-- L (Weight: 7)
问题:实现这个最优雅的方法是什么?我正在使用 LINQ 进行查询。
我知道我可以按 Cat1
分组,即:list.GroupBy(r => new { r.Cat1 })
,然后在每个组中迭代,在每个组内我可以按 Cat2 等分组,等等。但是看起来不是很优雅而且还很依赖层级顺序...
你可以这样做:
var nodes = list
.GroupBy(c1 => c1.Cat1.Name)
.Select(c1 => new Node
{
Name = c1.Key,
Weight = c1.Sum(x => x.Weight),
Children = c1
.GroupBy(c2 => c2.Cat2.Name)
.Select(c2 => new Node
{
Name = c2.Key,
Weight = c2.Sum(x => x.Weight),
Children = c2.Select(c3 => new Node
{
Name = c3.Cat3.Name,
Weight = c3.Weight,
Children = new List<Node>()
}).ToList()
}).ToList()
}).ToList();
我有这个class:
class Foo
{
Category1 Cat1;
Category2 Cat2;
Category3 Cat3;
decimal Weight;
}
每个Categoryi
都有一个string Name
属性
所以 Foos
的列表可能如下所示:
Cat1 Cat2 Cat3 Weight
--------------------------------
AP SG X 10
AP SG S 5
AP J X 5
AP AR S 10
NE R L 7
...
我想从列表中创建一棵树。即:
一个节点列表,作为一个节点:
class Node
{
string Name;
decimal Weight;
List<Node> Children;
}
使用此层次结构顺序:Category1、Category2、Category3,树将如下所示:
|--AP (Weight: 30)
| |
| |--SG (Weight: 15)
| | |-- X (Weight: 10)
| | |-- S (Weight: 5)
| |
| |--J (Weight: 5)
| | |-- X (Weight: 5)
| |
| |--AR (Weight: 10)
| |-- S (Weight: 10)
|
|--NE (Weight: 7)
|
|-- R (Weight: 7)
|-- L (Weight: 7)
问题:实现这个最优雅的方法是什么?我正在使用 LINQ 进行查询。
我知道我可以按 Cat1
分组,即:list.GroupBy(r => new { r.Cat1 })
,然后在每个组中迭代,在每个组内我可以按 Cat2 等分组,等等。但是看起来不是很优雅而且还很依赖层级顺序...
你可以这样做:
var nodes = list
.GroupBy(c1 => c1.Cat1.Name)
.Select(c1 => new Node
{
Name = c1.Key,
Weight = c1.Sum(x => x.Weight),
Children = c1
.GroupBy(c2 => c2.Cat2.Name)
.Select(c2 => new Node
{
Name = c2.Key,
Weight = c2.Sum(x => x.Weight),
Children = c2.Select(c3 => new Node
{
Name = c3.Cat3.Name,
Weight = c3.Weight,
Children = new List<Node>()
}).ToList()
}).ToList()
}).ToList();