2009-01-14 6 views
21

Comment créer un regroupement imbriqué pour le tableau ci-dessous, en utilisant LINQ? Je veux regrouper par Code, puis par Mktcode.Comment créer un dictionnaire groupé imbriqué à l'aide de LINQ?

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 

Je voudrais un dictionnaire, à la fin, comme

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

Ainsi, les valeurs de ce dictionnaire serait

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

Répondre

26

Je pense que de cette façon:

  • Vous groupant principalement par le code, alors que le premier ne
  • Pour chaque groupe, vous avez encore une liste de résultats - vous devez donc appliquer une autre regroupement là.

Quelque chose comme:

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

Cela vous donnera un Dictionary<Code, Lookup<MktCode, Id>> - je pense que ce que vous voulez. C'est complètement non testé cependant.

+5

Bon sang, vous avez raison. Votre pouvoir mental est simplement incroyable. – Graviton

16

Vous pouvez construire (LookUps types de Dictionnaire < , Liste < >>) en utilisant group by into

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

Des idées sur la façon de convertir des groupes en type de dictionnaire? – Graviton

+5

groups.ToDictionary (g => g.Key, g => g.ToList()) –

12

Voilà comment je le ferais:

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

est ici la rupture du processus:

Groupe par les éléments de code, et de créer un dictionnaire externe où la clé est que le code.

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

Pour chacune des clés du dictionnaire externe, regroupez les éléments par Mktcode et créez un dictionnaire interne.

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

Pour chacune des clés du dictionnaire interne, projetez l'identifiant de ces éléments et convertissez-le en liste.

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

C'est celui que je comprends. Merci! – orad

Questions connexes