如何使用LINQ创建嵌套的group-by字典?

时间:2022-07-24 11:10:43

How would I create a nested grouping for the table below, using LINQ? I want to group by Code, then by Mktcode.

如何使用LINQ为下表创建嵌套分组?我想按代码分组,然后按Mktcode分组。

Code Mktcode Id
==== ======= ====
1    10      0001 
2    20      0010 
1    10      0012 
1    20      0010 
1    20      0014 
2    20      0001
2    30      0002
1    30      0002
1    30      0005

I'd like a dictionary, in the end, like

我最喜欢的是字典

Dictionary<Code, List<Dictionary<Mktcode, List<Id>>>>

So the values of this dictionary would be

所以这本词典的价值就是

{1, ({10,(0001,0012)}, {20,(0010,0014)}, {30, (0002, 0005)})},
{2, ({20,(0001, 0010)}, {30, (0020)} )}

3 个解决方案

#1


26  

I'd think of it this way:

我会这样想的:

  • You're primarily grouping by code, so do that first
  • 您主要是按代码分组,所以首先要这样做
  • For each group, you've still got a list of results - so apply another grouping there.
  • 对于每个组,您仍然有一个结果列表 - 所以在那里应用另一个分组。

Something like:

就像是:

var groupedByCode = source.GroupBy(x => x.Code);

var groupedByCodeAndThenId = groupedByCode.Select(group =>
    new { Key=group.Key, NestedGroup = group.ToLookup
                                         (result => result.MktCode, result => result.Id));

var dictionary = groupedByCodeAndThenId.ToDictionary
    (result => result.Key, result => result.NestedGroup);

That will give you a Dictionary<Code, Lookup<MktCode, Id>> - I think that's what you want. It's completely untested though.

这会给你一个字典 > - 我想这就是你想要的。但它完全未经测试。 ,lookup>

#2


16  

You can build lookups (Kinds of Dictionary<,List<>>) using group by into

您可以使用group by into构建查找(Dictionary of Dictionary <,List <>>)

var lines = new []
{
    new {Code = 1, MktCode = 10, Id = 1},
    new {Code = 2, MktCode = 20, Id = 10},
    new {Code = 1, MktCode = 10, Id = 12},
    new {Code = 1, MktCode = 20, Id = 10},
    new {Code = 1, MktCode = 20, Id = 14},
    new {Code = 2, MktCode = 20, Id = 1},
    new {Code = 2, MktCode = 30, Id = 2},
    new {Code = 1, MktCode = 30, Id = 2},
    new {Code = 1, MktCode = 30, Id = 5},
};

var groups = from line in lines
    group line by line.Code
    into codeGroup
    select new
    {
        Code = codeGroup.Key,
        Items = from l in codeGroup
            group l by l.MktCode into mktCodeGroup
            select new
            {
                MktCode = mktCodeGroup.Key, 
                Ids = from mktLine in mktCodeGroup
                    select mktLine.Id
            }
    };

#3


12  

Here's how I'd do it:

我是这样做的:

Dictionary<Code, Dictionary<MktCode, List<Id>>> myStructure =
  myList
    .GroupBy(e => e.Code)
    .ToDictionary(
      g => g.Key,
      g => g
        .GroupBy(e => e.Mktcode)
        .ToDictionary(
          g2 => g2.Key,
          g2 => g2.Select(e => e.Id).ToList()
        )
   )

Here's the breakdown of the process:

这是过程的细分:

Group the elements by Code, and create an outer dictionary where the key is that code.

按代码对元素进行分组,并创建一个外部字典,其中键是该代码。

  myList
    .GroupBy(e => e.Code)
    .ToDictionary(
      g => g.Key,

For each of the keys in the outer dictionary, regroup the elements by Mktcode and create an inner dictionary.

对于外部字典中的每个键,通过Mktcode重新组合元素并创建内部字典。

      g => g
        .GroupBy(e => e.Mktcode)
        .ToDictionary(
          g2 => g2.Key,

For each of the keys in the inner dictionary, project the id of those elements and convert that to a list.

对于内部字典中的每个键,投影这些元素的id并将其转换为列表。

          g2 => g2.Select(e => e.Id).ToList()
        )
   )

#1


26  

I'd think of it this way:

我会这样想的:

  • You're primarily grouping by code, so do that first
  • 您主要是按代码分组,所以首先要这样做
  • For each group, you've still got a list of results - so apply another grouping there.
  • 对于每个组,您仍然有一个结果列表 - 所以在那里应用另一个分组。

Something like:

就像是:

var groupedByCode = source.GroupBy(x => x.Code);

var groupedByCodeAndThenId = groupedByCode.Select(group =>
    new { Key=group.Key, NestedGroup = group.ToLookup
                                         (result => result.MktCode, result => result.Id));

var dictionary = groupedByCodeAndThenId.ToDictionary
    (result => result.Key, result => result.NestedGroup);

That will give you a Dictionary<Code, Lookup<MktCode, Id>> - I think that's what you want. It's completely untested though.

这会给你一个字典 > - 我想这就是你想要的。但它完全未经测试。 ,lookup>

#2


16  

You can build lookups (Kinds of Dictionary<,List<>>) using group by into

您可以使用group by into构建查找(Dictionary of Dictionary <,List <>>)

var lines = new []
{
    new {Code = 1, MktCode = 10, Id = 1},
    new {Code = 2, MktCode = 20, Id = 10},
    new {Code = 1, MktCode = 10, Id = 12},
    new {Code = 1, MktCode = 20, Id = 10},
    new {Code = 1, MktCode = 20, Id = 14},
    new {Code = 2, MktCode = 20, Id = 1},
    new {Code = 2, MktCode = 30, Id = 2},
    new {Code = 1, MktCode = 30, Id = 2},
    new {Code = 1, MktCode = 30, Id = 5},
};

var groups = from line in lines
    group line by line.Code
    into codeGroup
    select new
    {
        Code = codeGroup.Key,
        Items = from l in codeGroup
            group l by l.MktCode into mktCodeGroup
            select new
            {
                MktCode = mktCodeGroup.Key, 
                Ids = from mktLine in mktCodeGroup
                    select mktLine.Id
            }
    };

#3


12  

Here's how I'd do it:

我是这样做的:

Dictionary<Code, Dictionary<MktCode, List<Id>>> myStructure =
  myList
    .GroupBy(e => e.Code)
    .ToDictionary(
      g => g.Key,
      g => g
        .GroupBy(e => e.Mktcode)
        .ToDictionary(
          g2 => g2.Key,
          g2 => g2.Select(e => e.Id).ToList()
        )
   )

Here's the breakdown of the process:

这是过程的细分:

Group the elements by Code, and create an outer dictionary where the key is that code.

按代码对元素进行分组,并创建一个外部字典,其中键是该代码。

  myList
    .GroupBy(e => e.Code)
    .ToDictionary(
      g => g.Key,

For each of the keys in the outer dictionary, regroup the elements by Mktcode and create an inner dictionary.

对于外部字典中的每个键,通过Mktcode重新组合元素并创建内部字典。

      g => g
        .GroupBy(e => e.Mktcode)
        .ToDictionary(
          g2 => g2.Key,

For each of the keys in the inner dictionary, project the id of those elements and convert that to a list.

对于内部字典中的每个键,投影这些元素的id并将其转换为列表。

          g2 => g2.Select(e => e.Id).ToList()
        )
   )