2010-04-27 11 views
12

Ho una lista di tuple stringa, dire (P1, P2)Ordina e raggruppa in LINQ

Mi piacerebbe sapere se c'è una dichiarazione LINQ dove potevo gruppo da P1 (in ordine crescente), e avere quel gruppo contiene tutti i valori P2 per il gruppo (in ordine decrescente).

Per l'input: ("A", "B"), ("A", "C"), ("D", "B") Mi piacerebbe ottenere due gruppi: "A" e "D" (in questo ordine, sempre) dove il gruppo "A" contiene "C" e "B" (in quell'ordine, ogni volta) e il gruppo "D" contiene, beh, "B".

Ciò è possibile con le classi LINQ integrate o devo iterare i gruppi e ordinarli da solo?

risposta

20

No, non è difficile - devi solo tenere traccia di se stai guardando un gruppo o elementi all'interno del gruppo. Ecco un esempio di query:

var query = from tuple in tuples 
      orderby tuple.P1 
      group tuple.P2 by tuple.P1 into g 
      select new { Group = g.Key, 
         Elements = g.OrderByDescending(p2 => p2) }; 

Ecco un esempio completo (evitando tipo .NET 4 di Tuple solo per semplicità, se si sta utilizzando .NET 3.5):

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class MyTuple 
{ 
    public string P1 { get; set; } 
    public string P2 { get; set; } 
} 

class Test 
{ 
    static void Main() 
    { 
     List<MyTuple> tuples = new List<MyTuple> 
     { 
      new MyTuple { P1 = "A", P2 = "B" }, 
      new MyTuple { P1 = "A", P2 = "C" }, 
      new MyTuple { P1 = "D", P2 = "B" }, 
     }; 

     var query = from tuple in tuples 
      orderby tuple.P1 
      group tuple.P2 by tuple.P1 into g 
      select new { Group = g.Key, 
         Elements = g.OrderByDescending(p2 => p2) }; 

     foreach (var group in query) 
     { 
      Console.WriteLine("{0}:", group.Group); 
      foreach (var value in group.Elements) 
      { 
       Console.WriteLine(" {0}", value); 
      } 
     } 
    } 
} 

Nota che può essere un po 'più semplice se sei felice di fare l'ordinamento su una base "necessità di sapere":

var query = from tuple in tuples 
    orderby tuple.P1 
    group tuple.P2 by tuple.P1; 

foreach (var group in query) 
{ 
    Console.WriteLine("{0}:", group.Key); 
    foreach (var value in group.OrderByDescending(x => x)) 
    { 
     Console.WriteLine(" {0}", value); 
    } 
} 
+0

impressionante. Vado con la risposta nel primo (e secondo) pannello (i). Stavo provando qualcosa di simile al tuo terzo pannello e mi ha frustrato il fatto che dovessi dichiarare l'ordine in due diversi posti: dove erano i dati e dove era usato. Non pensavo di mettere l'Ordine nella selezione. Inoltre, non ho esperienza di .NET 4.0 Tuple - tutto a tempo debito. :-) – Jono

+0

La domanda include l'ordine decrescente, ma nella risposta entrambi sono in ordine crescente. Ho perso qualcosa? – SerG

+0

@SerG: È possibile che la domanda sia stata modificata entro 5 minuti dalla richiesta, ma dopo che ho risposto - o che mi è sfuggito. Modifica ora. –

4
List<Tuple<string, string>> tuples = // 
var grouped = tuples.GroupBy(t => t.First) 
    .OrderBy(grp => grp.Key) 
    .Select(grp => new { Key = grp.Key, Items = grp.OrderBy(t => t.Second) }); 
Problemi correlati