2010-06-04 18 views
8

Mi sto solo prendendo in giro Linq e mi sto divertendo un sacco! Uno può aiutare con una query per questo:
Ho un elenco di dati: LINQ: Selezione di elementi da un elenco (Raggruppa per/Seleziona/Somma e Max!)

 
    Key Value 
    Aaa 12 
    AaA 10 
    AAa 5 
    BBB 2 
    Bbb 1 
1. Voglio gruppo da Key.ToUpper()
2. Per ogni gruppo ho bisogno del Max (Valore) & Somma (value)
3. per ogni gruppo voglio selezionare le voci C'è la valore = Max (valore)
il risultato finale dovrebbe essere simile a questo:!
 
    Key Max Total 
    AaA 12 27 
    AAa 12 27 
    Bbb 2 3
Grazie!

aggiornamento, in realtà ho anche bisogno la chiave dalla data di entrata massima:

 
    Key Max Total Correct 
    AaA 12 27 Aaa 
    AAa 12 27 Aaa 
    Bbb 2 3  BBB

+3

Suoni sospettosamente come i compiti. –

+0

Oppure una domanda di intervista ... i compiti a casa di solito non coinvolgono "ToUpper" –

+0

Nessuno dei due, vedresti dal mio profilo che sono un po 'di compiti passati :) E non proprio un programmatore professionista [più], solo per divertimento :) –

risposta

16

:)

var results = 
    from kvp in source 
    group kvp by kvp.Key.ToUpper() into g 
    select new 
    { 
    Group = g, 
    Max = g.Max(kvp => kvp.Value), 
    Total = g.Sum(kvp => kvp.Value) 
    } into ag 
    from x in ag.Group //SelectMany 
    where x.Value != ag.Max 
    //for the update to the question - note: possibly ambiguous 
    let correct = ag.Group.Where(y => y.Value == ag.Max).First().Key 
    select new 
    { 
    Key = x.Key, 
    Max = ag.Max, 
    Total = ag.Total, 
    Correct = correct 
    }; 

ho un po 'come la domanda a causa di tutte le piccole parti (alcuni sono usati raramente) che sono necessario per fare la risposta.


Max = g.Max(kvp => kvp.Value), 
Total = g.Sum(kvp => kvp.Value) 

Esecuzione di più aggregazioni su un gruppo è molto semplice, ma impegnativo se non si sa come.


select a into b 

Questa clausola prende tutto quello che è successo prima e inizia una nuova query con il bersaglio. Senza di essa, avrei dovuto iniziare una nuova query come questa:

var A = ... select a 

var B = from b in A 

E 'importante notare che la clausola select into rimuove kvp e g dal campo di applicazione.


from b in source 
    from a in b.A //SelectMany 

Questa "spacchettamento" della collezione bambino compie il mio messaggio relativo a B è in una query su un di. A differenza del sovraccarico predefinito Enumerable.SelectMany, lascia il genitore (b) in ambito.


where x.Value != ag.Max 

Confrontando proprietà di un bambino con la proprietà di un genitore? Delizioso. È importante ricordare di scoppiare where ogni volta che si desidera filtrare, anche se è stato appena raggruppato (non esiste HAVING).

+0

Wowsers, risposta rapida e perfetta. Grazie! –

+0

Felice di poter solleticare le parti meno utilizzate di LINQ. Penso che la piccola aggiunta lo renda un po 'più complicato? –

+0

Aggiornato. L'ambiguità deriva dalla possibilità che più righe possano avere lo stesso valore massimo. Voglio anche ricordare che se tutte le righe di una determinata chiave hanno lo stesso valore, non viene restituita nessuna riga. –

Problemi correlati