2009-03-05 7 views

Répondre

17

C'est l'opérateur GroupBy. Utilisez-vous LINQ to Objects?

Voici un exemple:

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

qui fait le groupement - pouvez-vous gérer le reste vous-même?

+2

Il est également possible de remplacer la boucle interne avec 'String.Join (« », group.ToArray())', tant que le nombre d'éléments est pas très grande. –

+0

Merci! Je vais apprendre moi-même LINQ au lieu de m'embêter constamment ;-) –

+8

Suis-je le seul à avoir remarqué que l'homme fait du sport alors que les hobbies de la femme sont en train de dormir et de boire? Tu es terrible Jon Skeet! – Carter

5

Voyez si cette solution vous aide:

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 l'aspect _concat de votre question, en utilisant:

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

L'émission en sortie foreach dans bruno conde et les réponses de Jon Skeet peut devenir:

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

... et vous obtiendrez le format précis de sortie de résultat que vous avez demandé fo r (oui, je sais que les autres ont déjà résolu votre problème, mais il est difficile de résister!)

+0

c'est comme la fonction 'GROUP_CONCAT' de MySQL. utile. –

+0

@Moshe LI deviner ces jours je pourrais remplacer 'group.Select (g => g.Hobby) .AsJoined (", ")' avec 'String.Join (", ", à partir de g dans le groupe sélectionnez g.Hobby)' (Ceci nécessite la surcharge de 'String.Join' qui prend' IEnumerable ', qui a été introduit dans .NET 4.0) –

+0

ou simplement utiliser sur' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''. –

2

Pour le faire dans une déclaration LINQ. Je ne recommanderais pas le code, mais cela montre que cela pourrait être fait.

  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

Ou bien nous pouvons faire les suivantes-

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

toutes les réponses n'est pas assez bon;

parce que c'est une requête db, mais nous faisons tous que juste en mémoire;

diff est que certaines opérations en mémoire occuce une erreur ne peut pas trans pour stocker l'expression;

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 
Questions connexes