2011-09-02 61 views
145

này là khá đơn giản nhưng tôi đang ở một mất mát: Với kiểu này tập hợp dữ liệu:LINQ với groupby và đếm

UserInfo(name, metric, day, other_metric) 

và tập dữ liệu mẫu này:

joe 1 01/01/2011 5 
jane 0 01/02/2011 9 
john 2 01/03/2011 0 
jim 3 01/04/2011 1 
jean 1 01/05/2011 3 
jill 2 01/06/2011 5 
jeb 0 01/07/2011 3 
jenn 0 01/08/2011 7 

tôi d muốn truy xuất một bảng liệt kê các số liệu theo thứ tự (0,1,2,3 ..) với tổng số lần đếm xảy ra. Vì vậy, từ bộ này, bạn muốn kết thúc với:

0 3  
1 2  
2 2  
3 1 

Tôi đang phải vật lộn với cú pháp LINQ nhưng đang bị mắc kẹt trên nơi để đặt một groupby và đếm .... bất kỳ sự giúp đỡ ??

Bài chỉnh sửa: Tôi chưa bao giờ có thể nhận được câu trả lời đã đăng để làm việc vì họ luôn trả về một bản ghi với số lượng các số đếm khác nhau. Tuy nhiên, tôi đã có thể tổng hợp một ví dụ LINQ to SQL đã hoạt động:

 var pl = from r in info 
       orderby r.metric  
       group r by r.metric into grp 
       select new { key = grp.Key, cnt = grp.Count()}; 

Kết quả này cho tôi một bộ hồ sơ được đặt hàng với 'số liệu' và số lượng người dùng được liên kết với mỗi số liệu. Tôi rõ ràng mới cho LINQ nói chung và mắt chưa được đào tạo của tôi cách tiếp cận này có vẻ rất giống với cách tiếp cận LINQ tinh khiết nhưng đã cho tôi một câu trả lời khác nhau.

+0

Có, nhưng lời giải thích của jimmy đã giúp tôi nhiều hơn thế. Tuy nhiên tôi chưa bao giờ có thể lấy ví dụ của mình để làm việc nhưng nó đã dẫn tôi theo một hướng mới. – Gio

Trả lời

254

Sau khi gọi GroupBy, bạn nhận được một loạt các nhóm IEnumerable<Grouping>, nơi mỗi nhóm tự cho thấy nhiều Key sử dụng để tạo nhóm và cũng là một IEnumerable<T> của bất cứ mặt hàng nằm trong tập hợp dữ liệu ban đầu của bạn. Bạn chỉ cần gọi Count() trên Nhóm đó để nhận tổng số phụ.

foreach(var line in data.GroupBy(info => info.metric) 
         .Select(group => new { 
          Metric = group.Key, 
          Count = group.Count() 
         }) 
         .OrderBy(x => x.Metric) 
{ 
    Console.WriteLine("{0} {1}", line.Metric, line.Count); 
} 


Đây là một câu trả lời nhanh chóng rực rỡ nhưng tôi đang gặp một chút vấn đề với dòng đầu tiên, đặc biệt là "data.groupby (info => info.metric)"

tôi giả sử bạn đã có một danh sách/mảng của một số class trông giống như

class UserInfo { 
    string name; 
    int metric; 
    ..etc.. 
} 
... 
List<UserInfo> data = ..... ; 

Khi bạn làm data.GroupBy(x => x.metric), nó có nghĩa là "cho mỗi phần tử x trong IEnumerable xác định bởi data, tính toán nó .metric, sau đó nhóm tất cả các yếu tố với số liệu tương tự thành một Grouping và trả về một IEnumerable của tất cả các nhóm kết quả. Do bạn thiết lập ví dụ dữ liệu

<DATA>   | Grouping Key (x=>x.metric) | 
joe 1 01/01/2011 5 | 1 
jane 0 01/02/2011 9 | 0 
john 2 01/03/2011 0 | 2 
jim 3 01/04/2011 1 | 3 
jean 1 01/05/2011 3 | 1 
jill 2 01/06/2011 5 | 2 
jeb 0 01/07/2011 3 | 0 
jenn 0 01/08/2011 7 | 0 

nó sẽ dẫn đến kết quả sau sau khi groupby:

(Group 1): [joe 1 01/01/2011 5, jean 1 01/05/2011 3] 
(Group 0): [jane 0 01/02/2011 9, jeb 0 01/07/2011 3, jenn 0 01/08/2011 7] 
(Group 2): [john 2 01/03/2011 0, jill 2 01/06/2011 5] 
(Group 3): [jim 3 01/04/2011 1] 
+0

Đây là một câu trả lời nhanh chóng tuyệt vời nhưng tôi gặp vấn đề với dòng đầu tiên, cụ thể là "data.groupby (info => info.metric)". Rõ ràng 'dữ liệu' là tập dữ liệu hiện tại nhưng represet 'info.metric' là gì? định nghĩa lớp học? – Gio

+0

"info.metric" sẽ là thuộc tính/trường số liệu trên lớp UserInfo mà bạn đã đề cập trong câu hỏi của mình. –

+1

Cảm ơn bạn đã tìm ra nhưng thực tế điều này dường như cho tôi một giá trị duy nhất - cụ thể là tổng số lượng số liệu khác nhau. Trong ví dụ này, tôi nhận được "số liệu 4" cho biết tôi có bao nhiêu số lượng khác nhau. – Gio

13
userInfos.GroupBy(userInfo => userInfo.metric) 
     .OrderBy(group => group.Key) 
     .Select(group => Tuple.Create(group.key, group.Count())); 
26

Giả sử userInfoList là một List<UserInfo>:

 var groups = userInfoList 
      .GroupBy(n => n.metric) 
      .Select(n => new 
      { 
       MetricName = n.Key, 
       MetricCount = n.Count() 
      } 
      ) 
      .OrderBy(n => n.MetricName); 

Chức năng lambda cho GroupBy(), n => n.metric mea ns rằng nó sẽ nhận được trường metric từ mọi đối tượng UserInfo gặp phải.Loại n tùy thuộc vào ngữ cảnh, trong lần xuất hiện đầu tiên là loại UserInfo, vì danh sách chứa UserInfo đối tượng. Trong lần xuất hiện thứ hai, n thuộc loại Grouping, bởi vì bây giờ là danh sách các đối tượng Grouping.

Grouping s có các phương pháp mở rộng như .Count(), .Key() và nhiều thứ khác bạn mong đợi. Cũng giống như bạn sẽ kiểm tra .Lenght trên string, bạn có thể kiểm tra .Count() trên một nhóm.

Các vấn đề liên quan