根据C#中的列表创建一个树,并进行分组

本文关键字:一个 列表 创建 根据 | 更新日期: 2023-09-27 18:20:07

我有这个类:

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

使用这个层次顺序:类别1、类别2、类别3,树看起来像这样:

|--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分组,等等。但它看起来不太优雅,也非常依赖于层次顺序

根据C#中的列表创建一个树,并进行分组

您可以这样做:

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