按嵌套列表对列表进行分组并删除与组不对应的元素

Posted

技术标签:

【中文标题】按嵌套列表对列表进行分组并删除与组不对应的元素【英文标题】:Group list by nested list and remove elements not corresponding to group 【发布时间】:2021-07-14 13:12:42 【问题描述】:

假设我有这样的结构(但AB 都有更多属性):

class C

    List<A> A  get; set; 


class A

    int Id  get; set; 
    string Name  get; set; 
    List<B> B  get; set; 


class B

    int Id  get; set; 
    string Name  get; set; 
    int GroupId  get; set; 

我想按B.GroupId 分组,并且只保留每个组中具有相应GroupId 值的元素。

这是一个示例数据:

[
    
        "Id": 1,
        "Name": "A1",
        "B": [
            
                "Id": 1,
                "Name": "B1",
                "GroupId": 1
            ,
            
                "Id": 2,
                "Name": "B2",
                "GroupId": 1
            ,
            
                "Id": 3,
                "Name": "B3",
                "GroupId": 2
            
        ]
    ,
    
        "Id": 2,
        "Name": "A2",
        "B": [
            
                "Id": 4,
                "Name": "B4",
                "GroupId": 1
            ,
            
                "Id": 5,
                "Name": "B5",
                "GroupId": 2
            ,
            
                "Id": 6,
                "Name": "B6",
                "GroupId": 3
            
        ]
    
]

作为一个决心,我希望有 3 个组:

Group 1:
    [
        
            "Id": 1,
            "Name": "A1",
            "B": [
                
                    "Id": 1,
                    "Name": "B1",
                    "GroupId": 1
                ,
                
                    "Id": 2,
                    "Name": "B2",
                    "GroupId": 1
                
            ]
        ,
        
            "Id": 2,
            "Name": "A2",
            "B": [
                
                    "Id": 4,
                    "Name": "B4",
                    "GroupId": 1
                
            ]
        
    ]

Group 2:
    [
        
            "Id": 1,
            "Name": "A1",
            "B": [
                
                "Id": 3,
                "Name": "B3",
                "GroupId": 2
            
            ]
        ,
        
            "Id": 2,
            "Name": "A2",
            "B": [
                
                    "Id": 5,
                    "Name": "B5",
                    "GroupId": 2
                
            ]
        
    ]

Group 3:
    [
        
            "Id": 2,
            "Name": "A2",
            "B": [
                
                    "Id": 6,
                    "Name": "B6",
                    "GroupId": 3
                
            ]
        
    ]

我发现我可以像这样按B.GroupId 分组:

from a in c
from b in a.B
group a by b.GroupId

但是我如何摆脱那些GroupId 不在相应组中的元素呢?我尝试在foreach 循环中删除它们,但这会将它们从所有组中删除,而不仅仅是一个。

【问题讨论】:

【参考方案1】:

您可以尝试使用 Linq。这是“GroupBy”的示例

var jsonstring = File.ReadAllText("json1.json");
var objRoot = JsonConvert.DeserializeObject<List<A>>(jsonstring);
var result = objRoot.SelectMany(x => x.B)
                    .GroupBy(x => x.GroupId)
                    .ToDictionary(x => x.Key, y => y.ToArray());

编辑

var jsonstring = File.ReadAllText("json1.json");
var objRoot = JsonConvert.DeserializeObject<List<A>>(jsonstring);
var result = objRoot.SelectMany(AObj => AObj.B, (AObj, B) => new  AObj, B )
    .GroupBy(BObj => BObj.B.GroupId)
    .ToDictionary(x => x.Key, y => y.Select(y =>
                new A
                
                    Id = y.AObj.Id,
                    Name = y.AObj.Name,
                    B = new List<B>  y.B 
                ).GroupBy(x => x.Id).ToList());
Console.WriteLine(JsonConvert.SerializeObject(result));

【讨论】:

每个组只返回List&lt;B&gt;。我需要为每个组提供List&lt;A&gt; 那么创建一个新的A 对象是唯一的方法吗?我希望避免这种情况,因为我的现实生活中的 A 对象有 100 多个属性,其中大多数是复杂的(对象、列表等)。

以上是关于按嵌套列表对列表进行分组并删除与组不对应的元素的主要内容,如果未能解决你的问题,请参考以下文章

如何通过第一个元素对列表内的列表进行分组?

如何按n个元素对python中的元素进行分组[重复]

在 jQuery 中按数据属性对 HTML 元素进行分组和计数

pandas相同元素不同顺序合并之移形换位

python怎么获取list的某个元素的位置

C# LINQ - 按属性分组列表,然后按不同组选择