2013-04-18 5 views
5

Ho una lista come la seguente:Usa List.ToLookup()

var products = new List<Product> 
{ 
    new Product { Id = 1, Category = "Electronics", Value = 15.0 }, 
    new Product { Id = 2, Category = "Groceries", Value = 40.0 }, 
    new Product { Id = 3, Category = "Garden", Value = 210.3 }, 
    new Product { Id = 4, Category = "Pets", Value = 2.1 }, 
    new Product { Id = 5, Category = "Electronics", Value = 19.95 }, 
    new Product { Id = 6, Category = "Pets", Value = 5.50 }, 
    new Product { Id = 7, Category = "Electronics", Value = 250.0 }, 
}; 

Voglio gruppo per categoria e ottenere il somma di 'valori' che appartiene a quella categoria .. Esempio: Elettronica : 284.95

Mentre posso farlo in qualche altro modo, voglio imparare l'uso di Look-Up.

È possibile ottenere questi 2 valori (categoria e valore) in una ricerca? Se sì, come posso farlo?

risposta

5

Probabilmente si desidera utilizzare ToDictionary() invece di ToLookup

var dict = products 
    .GroupBy(p => p.Category) 
    .ToDictionary(grp => grp.Key, grp => grp.Sum(p => p.Value)); 

foreach(var item in dict) 
{ 
    Console.WriteLine("{0} = {1}", item.Key, item.Value); 
} 
+0

Ci sono più elementi con la stessa chiave nell'elenco: un dizionario non funzionerà. – TheEvilPenguin

+2

@TheEvilPenguin Sicuramente, c'è un 'GroupBy' prima della chiamata' ToDictionary'. – hvd

+0

@hvd Il mio errore - Ho letto la prima riga ed ero confuso sul motivo per cui un dizionario sarebbe più corretto della ricerca che l'OP vuole conoscere. – TheEvilPenguin

2

Non è necessario un Lookup. È possibile farlo con un semplice query:

var results = 
    from p in products 
    group p by p.Category into g 
    select new 
    { 
     Category = g.Key, 
     TotalValue = g.Sum(x => x.Value) 
    }; 
+1

'ToLookup' è una parte di LINQ troppo. – MarcinJuraszek

10

Quando si recupera da chiave da un Lookup, si comporta proprio come un raggruppamento, in modo da poter fare le cose in questo modo:

var productLookup = products.ToLookup(p => p.Category); 
var electronicsTotalValue = productLookup["Electronics"].Sum(p => p.Value); 
var petsTotalValue = productLookup["Pets"].Sum(p => p.Value); 
//etc 

var totalValue = products.Sum(p => p.Value); 
// I wouldn't use the Lookup here, the line above makes more sense and would execute faster 
var alsoTotalValue = productLookup.Sum(grp => grp.Sum(p => p.Value)); 
+0

Grazie! .. Solo curioso .. Posso inserire la seconda affermazione nella prima? In caso contrario, avrò bisogno di scorrere il productLookup per ottenere la somma di tutte le categorie. – ViV

+1

@ViV È possibile, ma in questo caso si ricreerà una ricerca ogni volta che si chiama. Ho aggiunto alcuni altri esempi di come è possibile estrarre vari totali, ma per alcuni di essi ha più senso saltare la ricerca. – TheEvilPenguin