2009-03-05 19 views

Trả lời

17

Đó là toán tử GroupBy. Bạn đang sử dụng LINQ to Objects?

Dưới đây là một ví dụ:

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

Điều đó không những nhóm - bạn có thể quản lý phần còn lại chính mình?

+2

Nó cũng có thể thay thế các vòng trong với 'String.Join ("", group.ToArray())', miễn là số phần tử không phải là rất lớn. –

+0

Cảm ơn! Tôi sẽ tìm hiểu LINQ bản thân mình thay vì liên tục bugging bạn ;-) –

+8

Tôi có phải là người duy nhất nhận thấy người đàn ông đó là thể thao trong khi sở thích của người phụ nữ đang ngủ và uống? Bạn đang khủng khiếp Jon Skeet! – Carter

5

Xem nếu giải pháp này giúp bạn:

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

lại các khía cạnh _concat câu hỏi của bạn, sử dụng:

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

Các foreach xuất ra trong conde bruno và câu trả lời của Jon Skeet có thể trở thành:

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

... và bạn sẽ nhận được định dạng kết quả đầu ra chính xác mà bạn đã yêu cầu r (vâng, tôi biết những người khác đã giải quyết được vấn đề của bạn, nhưng khó mà cưỡng lại được!)

+0

điều này giống như chức năng 'GROUP_CONCAT' của MySQL. hữu ích. –

+0

@Moshe LI đoán những ngày này tôi có thể thay thế 'group.Select (g => g.Hobby) .AsJoined (", ")' với 'String.Join (", ", từ g trong nhóm chọn g.Hobby)' (Điều này đòi hỏi sự quá tải của 'String.Join' có' IEnumerable ', được giới thiệu trong .NET 4.0) –

+0

hoặc chỉ sử dụng trên nhóm 3.5'. Chọn (g => g.Hobby) .ToArray() '. –

2

Để làm điều đó trong một Tuyên bố LINQ. Không có cách nào tôi muốn giới thiệu mã, nhưng nó cho thấy rằng nó có thể được thực hiện.

  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

Hoặc nếu không chúng ta có thể làm following-

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

tất cả các câu trả lời là không đủ tốt;

vì đây là truy vấn db, nhưng tất cả chúng ta làm điều đó chỉ trong bộ nhớ;

khác biệt là một số thao tác trong bộ nhớ sẽ xảy ra lỗi không thể chuyển sang biểu thức cửa hàng;

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