简体   繁体   English

从C#中的列表创建树,并进行分组

[英]Create a tree from a list in C#, with grouping

I have this class: 我有这个课:

 class Foo 
 {
    Category1 Cat1;
    Category2 Cat2;
    Category3 Cat3;
    decimal Weight;
 }

Each Categoryi has a string Name property 每个Categoryi都有一个string Name属性

So a list of Foos might look like this: 因此, 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
 ...

I want to create a tree from the list. 我想从列表中创建一棵树。 That is: 那是:
a list of nodes, being a node this: 节点列表,作为此节点:

 class Node
 {
    string Name;
    decimal Weight;
    List<Node> Children;
 }

Using this hierarchy order: Category1, Category2, Category3, the tree would look like this: 使用以下层次结构顺序: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)

Question: whats the most elegant way to achieve this? 问题:最优雅的方法是什么? I'm using LINQ for queries. 我正在使用LINQ进行查询。

I know I could group by Cat1 , ie: list.GroupBy(r => new { r.Cat1 }) , then iterate in every group and inside each group I could group by Cat2, etc, etc. But it doesn't seem very elegant and it is also very dependant on the hierarchy order... 我知道我可以按组Cat1 ,即: list.GroupBy(r => new { r.Cat1 })然后在每个组,每个组我可以CAT2组,等等,等等内部循环但似乎并不非常优雅,也非常取决于层次结构顺序...

You can do this: 你可以这样做:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM