2013-09-27 11 views
5

Data la seguente classe:C# GroupBy - La creazione di più livelli di raggruppamento

public class Transaction 
{ 
    public string Category { get; set; } 
    public string Form { get; set; } 
} 

Come ottengo un raggruppamento di operazioni che sono raggruppate sia dal Category e Form?

Fondamentalmente voglio che in uscita in questo modo:

Category 1 
    Form 1 
     Transaction1 
     Transaction2 
     Transaction3 
     ... 
    Form 2 
     Transaction1 
     Transaction2 
     Transaction3 
     ... 
Category 2 
    Form 1 
     Transaction1 
     Transaction2 
     Transaction3 
     ... 
    Form 2 
     Transaction1 
     Transaction2 
     Transaction3 
     ... 

risposta

6

ho finito con il seguente, perché il raggruppamento ha bisogno di essere completato prima l'iterazione sulla raccolta.

Seed alcune operazioni

var cats = new[] { "Category 1", "Category 2", "Category 3" }; 
var frms = new[] { "Form 1", "Form 2", "Form 3" }; 
var transactions = new List<Transaction>(); 

for (var i = 0; i <= 150; i++) 
{ 
    transactions.Add(new Transaction 
    { 
     Category = i % 2 == 0 ? cats[0] : i % 3 == 0 ? cats[1] : cats[2], 
     Form = i % 5 == 0 ? frms[0] : i % 7 == 0 ? frms[1] : frms[2] 
    }); 
} 

il raggruppamento

var groupedTransactions = transactions.GroupBy(x => x.Category) 
    .Select(x => new 
    { 
     Category = x.Key, 
     Forms = x.ToList() 
      .GroupBy(y => y.Form) 
    }); 

scrittura alla console

foreach (var group in groupedTransactions.OrderBy(x => x.Category)) 
{ 
    Console.WriteLine(group.Category); 
    foreach (var form in group.Forms.OrderBy(x => x.Key)) 
    { 
     Console.WriteLine("\t" + form.Key); 
     foreach (var transaction in form) 
     { 
      Console.WriteLine("\t\t" + transaction.Id); 
     } 
    } 
} 
6

Ecco un esempio utilizzando cicli foreach nidificati, io non sono sicuro di come si dovrebbe fare questo in una singola stringa di dichiarazioni LINQ, forse con un sacco di selectmanys?

var transactions = new[]{ 
    new{Category = "1", Form = "1", Title = "Trans1" }, 
    new{Category = "1", Form = "1", Title = "Trans2" }, 
    new{Category = "1", Form = "1", Title = "Trans3" }, 
    new{Category = "1", Form = "2", Title = "Trans1" }, 
    new{Category = "1", Form = "2", Title = "Trans2" }, 
    new{Category = "1", Form = "2", Title = "Trans3" }, 
    new{Category = "2", Form = "1", Title = "Trans1" }, 
    new{Category = "2", Form = "1", Title = "Trans2" }, 
    new{Category = "2", Form = "1", Title = "Trans3" }, 
    new{Category = "1", Form = "3", Title = "Trans1" }, 
    new{Category = "1", Form = "3", Title = "Trans2" }, 
    new{Category = "1", Form = "3", Title = "Trans3" }, 
}; 

foreach(var byCategory in transactions.GroupBy(x => x.Category)) 
{ 
    Console.WriteLine(byCategory.Key); 
    foreach(var byForm in byCategory.GroupBy(x => x.Form)) 
    { 
     Console.WriteLine("\t" + byForm.Key); 
     foreach(var trans in byForm) 
     { 
      Console.WriteLine("\t\t" + trans.Title); 
     } 
    } 
} 

solo perché ero curioso di ciò che sarebbe simile mi si avvicinò con la seguente, non si dovrebbe utilizzare questo in codice di produzione in quanto è ridicolo (se si dispone di una struttura di dati come questo dovrebbe essere rotto up in qualcosa di simile Dictionary<CategoryName, FormGroup> o qualcosa con i tipi significativi)

Dictionary<string, Dictionary<string, List<string>>> tooManyDictionaries = transactions 
     .GroupBy(x => x.Category) 
     .ToDictionary(
      catGroup => catGroup.Key, 
      catGroup => catGroup 
       .GroupBy(x => x.Form) 
       .ToDictionary(
        formGroup => formGroup.Key, 
        formGroup => formGroup.Select(x => x.Title).ToList())); 
Problemi correlati