2009-03-05 21 views

Respuesta

17

Ese es el operador de GroupBy. ¿Estás utilizando LINQ to Objects?

He aquí un ejemplo:

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

public class Test 
{ 
    static void Main() 
    { 
     var users = new[] 
     { 
      new { User="Bob", Hobby="Football" }, 
      new { User="Bob", Hobby="Golf" }, 
      new { User="Bob", Hobby="Tennis" }, 
      new { User="Sue", Hobby="Sleeping" }, 
      new { User="Sue", Hobby="Drinking" }, 
     }; 

     var groupedUsers = users.GroupBy(user => user.User); 

     foreach (var group in groupedUsers) 
     { 
      Console.WriteLine("{0}: ", group.Key); 
      foreach (var entry in group) 
      { 
       Console.WriteLine(" {0}", entry.Hobby); 
      } 
     } 
    } 
} 

que hace la agrupación - ¿Se puede gestionar el resto a ti mismo?

+2

También es posible sustituir el bucle interior con 'string.join ("", group.ToArray())', siempre y cuando el número de elementos no es muy grande. –

+0

¡Gracias! Aprenderé LINQ en lugar de molestarte constantemente ;-) –

+8

¿Soy el único que notó que el hombre practica deportes mientras que los pasatiempos de la mujer son dormir y beber? Eres terrible Jon Skeet! – Carter

5

A ver si esta solución le ayuda a:

List<User> users = new List<User>() 
{ 
    new User {Name = "Bob", Hobby = "Football" }, 
    new User {Name = "Bob", Hobby = "Golf"}, 
    new User {Name = "Bob", Hobby = "Tennis"}, 
    new User {Name = "Sue", Hobby = "Sleeping"}, 
    new User {Name = "Sue", Hobby = "Drinking"} 
}; 

var groupedUsers = from u in users 
     group u by u.Name into g 
     select new 
     { 
      Name = g.First<User>().Name, 
      Hobby = g.Select(u => u.Hobby) 
     }; 


foreach (var user in groupedUsers) 
{ 
    Console.WriteLine("Name: {0}", user.Name); 
    foreach (var hobby in user.Hobby) 
    { 
     Console.WriteLine("Hobby: {0}", hobby); 
    } 
} 
4

re el aspecto _concat de su pregunta, usando:

static class EnumerableExtensions 
{ 
    public static String AsJoined(this IEnumerable<String> enumerable) 
    { 
     return AsJoined(enumerable, ","); 
    } 

    public static String AsJoined(this IEnumerable<String> enumerable, String separator) 
    { 
     return String.Join(separator, enumerable.ToArray()); 
    } 
} 

El foreach dar salida en conde Bruno y respuestas de Jon Skeet puede llegar a ser:

Console.WriteLine("User:\tHobbies"); 
foreach (var group in groupedUsers) 
    Console.WriteLine("{0}:\t{1}", group.Key, group.Select(g => g.Hobby).AsJoined(", ")); 

... y obtendrá el formato de salida de resultado preciso que solicitó r (sí, sé que los demás ya han resuelto su problema, pero es difícil de resistir!)

+0

esto es como la función 'GROUP_CONCAT' de MySQL. útil. –

+0

@Moshe LI supongo que en estos días podría reemplazar 'group.Select (g => g.Hobby) .AsJoined (", ")' con 'String.Join (", ", de g en el grupo seleccione g.Hobby)' (Esto requiere la sobrecarga de 'String.Join' que toma' IEnumerable ', que se introdujo en .NET 4.0) –

+0

o simplemente usa en 3.5' ​​group.Select (g => g.Hobby) .ToArray() '. –

2

Para hacerlo en una declaración de Linq. No hay forma de que recomiende el código, pero muestra que podría hacerse.

  var groupedUsers = from user in users 
          group user by user.User into userGroup 
          select new 
          { 
           User = userGroup.Key, 
           userHobies = 
            userGroup.Aggregate((a, b) => 
             new { User = a.User, Hobby = (a.Hobby + ", " + b.Hobby) }).Hobby 
          } 
          ; 
     foreach (var x in groupedUsers) 
     { 
      Debug.WriteLine(String.Format("{0} {1}", x.User, x.userHobies)); 
     } 
3

O de lo que podemos hacer lo siguiente-

var users = new[] 
       { 
       new { User="Bob", Hobby="Football" }, 
       new { User="Bob", Hobby="Golf" }, 
       new { User="Bob", Hobby="Tennis" }, 
       new { User="Sue", Hobby="Sleeping" }, 
       new { User="Sue", Hobby="Drinking" }, 
       }; 

       var userList = users.ToList(); 
       var ug = (from user in users 
          group user by user.User into groupedUserList 
          select new { user = groupedUserList.Key, hobby = groupedUserList.Select(g =>g.Hobby)}); 

       var ug2 = (from groupeduser in ug 
          select new{ groupeduser.user, hobby =string.Join(",", groupeduser.hobby)}); 
-1

todas las respuestas no es suficiente;

porque esta es una consulta db, pero todos hacemos eso solo en la memoria;

diff es que alguna operación en la memoria va a ocupar un error que no puede transmitir para almacenar la expresión;

var list = db.Users.GroupBy(s=>s.User). 
      select(g=>new{user=g.Key,hobbys=g.select(s=>s.Hobby)}); // you can just do that from db 

var result=list.ToList(); // this is important,to query data to memory; 

var result2 = result.select(g=>new{user=g.Key,hobbyes=string.join(",",g.hobbyes)}; //then,do what you love in memory 
Cuestiones relacionadas