2009-03-05 10 views

Antwort

17

dass die GroupBy Operator ist. Verwenden Sie LINQ to Objects?

Hier ist ein Beispiel:

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

dass die Gruppierung tut - können Sie den Rest selbst verwalten?

+2

Es ist auch möglich, die innere Schleife mit 'String.Join („“, group.ToArray())', solange die Anzahl der Elemente zu ersetzen, nicht sehr groß ist. –

+0

Danke! Ich werde LINQ lernen, anstatt dich ständig zu nerven ;-) –

+8

Bin ich der Einzige, der bemerkt hat, dass der Mann Sport treibt, während die Hobbys der Frau schlafen und trinken? Du bist schrecklich Jon Skeet! – Carter

5

Prüfen Sie, ob diese Lösung Ihnen hilft:

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 der _concat Aspekt Ihrer Frage, mit:

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

Die Ausgabe foreach in bruno conde und Jon Skeet Antworten werden können:

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

... und Sie erhalten das genaue Ausgabeformat, das Sie gefragt haben r (ja, ich weiß, die anderen haben Ihr Problem bereits gelöst, aber es ist schwer zu widerstehen!)

+0

Das ist wie die 'GROUP_CONCAT' Funktion von MySQL. sinnvoll. –

+0

@Moshe LI denke, in diesen Tagen könnte ich ersetzen 'group.Select (g => g.Hobby) .AsJoined (", ")' mit 'String.Join (", ", aus g in Gruppe wählen g.Hobby)' (Dies erfordert die Überladung von 'String.Join', die' IEnumerable ', die in .NET 4.0 eingeführt wurde) –

+0

oder einfach auf 3.5' ​​group.Select (g => g.Hobby) .ToArray() '. –

2

Um es in einer Linq-Anweisung zu tun. Ich würde den Code auf keinen Fall empfehlen, aber es zeigt, dass es möglich ist.

  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

Oder sonst können wir die folgenden-

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

alle Antworten zu tun ist nicht gut genug;

weil dies eine DB-Abfrage ist, aber wir alle tun das nur im Speicher;

Diff ist, dass einige Operation im Speicher einen Fehler auftreten kann nicht trans, um Ausdruck zu speichern;

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