2009-01-14 18 views
21

Come si crea un raggruppamento nidificato per la tabella seguente, utilizzando LINQ? Voglio raggruppare per Code, quindi per Mktcode.Come posso creare un dizionario di gruppo annidato usando 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 

Vorrei un dizionario, alla fine, come

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

Quindi i valori di questo dizionario sarebbe

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

risposta

26

mi piacerebbe pensare in questo modo:

  • Stai principalmente raggruppamento per codice, in modo da farlo prima
  • Per ogni gruppo, hai ancora un elenco di risultati - così applicare un altro raggruppare lì.

Qualcosa di simile:

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

che vi darà un Dictionary<Code, Lookup<MktCode, Id>> - io penso questo è ciò che si desidera. È completamente non testato però.

+5

Geez, hai ragione. Il tuo potere mentale è semplicemente incredibile. – Graviton

16

È possibile costruire lookups (Tipi di dizionario < , Elenco < >>) utilizzando 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

Qualche idea su come convertire gruppi in tipo di dizionario? – Graviton

+5

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

12

Ecco come lo farei:

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

Ecco la ripartizione del processo:

Gruppo gli elementi di codice, e creare un dizionario esterna in cui la chiave è che il codice.

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

Per ciascuna delle chiavi nel dizionario esterno, raggruppare gli elementi tramite Mktcode e creare un dizionario interno.

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

Per ciascuna delle chiavi nel dizionario interno, proiettare l'id di tali elementi e convertirli in un elenco.

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

Questo è quello che ho capito. Grazie! – orad

Problemi correlati