2010-04-27 22 views
12

Tengo una lista de tuplas de cadenas, por ejemplo (P1, P2)en Ordenar y agrupar en LINQ

Me gustaría saber si hay una declaración de LINQ, donde pude grupo de P1 (en orden ascendente), y tener ese grupo contiene todos los valores P2 para el grupo (en orden descendente). Para entradas: ("A", "B"), ("A", "C"), ("D", "B") Me gustaría obtener dos grupos: "A" y "D" (en ese orden, cada vez) donde el grupo "A" contiene "C" y "B" (en ese orden, cada vez) y el grupo "D" contiene, bueno, "B".

¿Esto es posible con las clases integradas de LINQ o necesito iterar los grupos y ordenarlos yo mismo?

Respuesta

20

No, no es difícil, solo necesita hacer un seguimiento de si está mirando un grupo o elementos dentro del grupo. Aquí hay una consulta de ejemplo:

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

Aquí está un ejemplo completo (evitando .NET de 4 Tuple tipo sólo por simplicidad si está utilizando .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); 
      } 
     } 
    } 
} 

Tenga en cuenta que puede ser un poco más sencillo Si estás dispuesto a hacer el pedido en una "necesidad de saber":

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

impresionante. Voy con la respuesta en el primer (y segundo) panel (s). Estaba intentando algo similar a tu tercer panel y me frustró que tuviera que declarar el pedido en dos lugares diferentes: dónde se obtuvieron los datos y dónde se usaron. No pensé en poner el OrderBy en la selección. Además, no tengo experiencia con .NET 4.0 Tuple, todo a su debido tiempo. :-) – Jono

+0

La pregunta incluye el orden descendente, pero en la respuesta ambos son ascendentes. ¿Me he perdido algo? – SerG

+0

@SerG: es posible que la pregunta haya sido editada a los 5 minutos de haberla formulado, pero después de que respondí, o de que me la perdí. Editando ahora. –

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