【问题标题】:Nested GroupBy in C#C# 中的嵌套 GroupBy
【发布时间】:2018-11-20 12:34:22
【问题描述】:

拥有一个具有这种结构的对象:

public class GroupedObject
{
    public int id { get; set; }
    public string name { get; set; }
    public int value { get; set; }
    public string color { get; set; }
}

在这里,它按其属性之一进行分组,id

var myObj = someResponse
    .Select(d => new GroupedObject
    {
        id = d.id,
        name = d.name,
        value = d.value,
        color = d.color
    })
    .GroupBy(o => o.id)
    .ToDictionary(a => a.Key, a => a.Select(o => o).ToList());

结构是:

id - id, name, value, color
id - id, name, value, color
id - id, name, value, color

我想要做的是将它再次按name 分组,得到一个像这样的嵌套结构:

id - name - id, name, value, color
   - name - id, name, value, color
id - name - id, name, value, color
   - name - id, name, value, color 
   - name - id, name, value, color 
   - name - id, name, value, color 
id - name - id, name, value, color
   - name - id, name, value, color 
   - name - id, name, value, color 

尝试使用GroupBy 两次没有成功。也不是通过使用ToList 对其进行转换并在此之后进行分组。

 var myObj = someResponse
        .Select(d => new GroupedObject
        {
            id = d.id,
            name = d.name,
            value = d.value,
            color = d.color
        })
        .GroupBy(o => o.id).GroupBy(o => o.name)
        .ToDictionary(a => a.Key, a => a.Select(o => o).ToList());

【问题讨论】:

  • 当然,您必须将 ToDictionary 放在第一个 GroupBy 中,然后不要在 ToDictionary 中执行 a.Select...,而是使用 a.GroupBy 并将整个 ToDictionary 与另一个 .Select 链接。
  • 您想要的最终结果应该是这样的? Dictionary<int, Dictionay<string, List<GroupedObject>> - 外部Dictionaryint 键是id,内部Dictionarystring 键是name
  • @RandRandom 是

标签: c# dictionary group-by


【解决方案1】:

您在正确的轨道上,但是这里是实现两个嵌套级别分组的 LINQ:

someResponse
    .Select(d => new GroupedObject
    { 
        id = d.id,
        name = d.name,
        value = d.value,
        color = d.color
    })
    .GroupBy(o => o.id)
    .ToDictionary(
        a => a.Key,
        a => a.GroupBy(o => o.name).ToDictionary(o => o.Key, o => o));

这将导致对象类型:Dictionary<int, Dictionary<string, IGrouping<string, GroupedObject>>>

考虑到这一点,最后一个 IGrouping<string, GroupedObject> 类型可以更改/投影为不同的类型,在嵌套的 ToDictionary 调用中指定合适的 lamda:

例如将调用更改为ToDictionary(o => o.Key, o => o.ToList()) 结果为Dictionary<int, Dictionary<string, List<GroupedObject>>>

【讨论】:

  • 可能想将o => o 更改为o => o.ToList() 以“解决”该组并获得以下类型:Dictionary<int, Dictionary<string, List<GroupedObject>> .. 延迟
  • @RandRandom 我同意,这就是我用那个例子编辑问题的原因,我只是想展示 OP 的可能性,因为我不确定他真正想要什么类型
【解决方案2】:

使用理解语法可能更容易:

var myObj = from sr in someResponse
    .Select(d => new GroupedObject
    {
        id = d.id,
        name = d.name,
        value = d.value,
        color = d.color
    })
    group sr by sr.id into g1
    select new {
       ID = g1.Key,
       NamesGroup = from n in g1
                    group n by n.name into g2
                    select new {
                      Name = g2.Key,
                      ...
                    }
    };

注意:如果你从 LINQPad.net 下载了很棒的 LINQPad,在 Samples 中你会发现一个使用 Northwind 示例数据库的非常好的嵌套分组示例。

【讨论】:

    猜你喜欢
    • 2016-06-17
    • 2020-08-20
    • 1970-01-01
    • 2020-11-25
    • 2014-11-28
    • 1970-01-01
    • 1970-01-01
    • 2022-11-04
    • 2014-08-13
    相关资源
    最近更新 更多