2011-09-02 12 views
145

これは非常に単純ですが、私は途方に暮れてよ: データセットのこのタイプを考える:GROUPBYとLINQとカウント

UserInfo(name, metric, day, other_metric) 

と、このサンプルデータセット:私は「

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 

カウントが発生した回数の合計(0,1,2,3 ..)でメトリックをリストした表を検索したい。したがって、このセットから、あなたは、で終わるだろう:私はLINQの構文に取り組んだが、GROUPBYを入れてカウントする場所に貼り付けられています

0 3  
1 2  
2 2  
3 1 

.... 任意のヘルプ?

POST編集:投稿数が異なる1つのレコードが常に返されるため、投稿された回答を得ることができませんでした。この結果は、「メトリック」とそれぞれに関連付けられているユーザの数でくれたレコードの順序集合を与えた

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

:しかし、私は一緒に仕事をしたLINQ SQLに例を置くことができました。私はLINQの一般的な新機能です。私の未熟な目には、このアプローチは純粋なLINQのアプローチと非常によく似ていますが、私には別の答えが与えられています。

+0

はい、私は持っていますが、ジミーの説明は私をもっと助けました。しかし、私は決して働くために彼の例を得ることができませんでしたが、それは私を新しい方向に導いてくれました。 – Gio

答えて

254

GroupByを呼び出した後、あなたはどんなアイテムのIEnumerable<T>があなたの元のデータセット内にある各自身のグループ化は、グループを作成するために使用さKeyを公開し、またあるグループIEnumerable<Grouping>のシリーズを、得ます。小計を得るには、そのグループ化でCount()に電話するだけです。


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); 
} 
は、これが見事に迅速な返事だったが、私は最初の行で問題のビットを抱えている、特に "data.groupby(情報=> info.metric)"

私はあなたがすでに

class UserInfo { 
    string name; 
    int metric; 
    ..etc.. 
} 
... 
List<UserInfo> data = ..... ; 
のように見えるいくつかの classのリスト/配列を持っていると仮定しています

あなたがdata.GroupBy(x => x.metric)を行うと、それは「dataで定義されてIEnumerableの各要素xため、Groupingにグループそして、それは.metricだ同じメトリックを持つすべての要素を計算し、すべての結果のグループのIEnumerableを返すことを意味します。

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

ラムダ関数:

<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 

のあなたの例のデータセットを考えると、それはGROUPBY後に次のような結果につながる:List<UserInfo>

(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

これはすばやく簡単な返信でしたが、最初の行に問題があります。具体的には「data.groupby(info => info.metric)」です。普通の 'data'は現在のデータセットですが、 'info.metric' represetは何ですか?クラス定義? – Gio

+0

"info.metric"は、質問に記載したUserInfoクラスのメトリックプロパティ/フィールドです。 –

+1

ありがとうございましたが、実際これは私に単一の値、つまり異なるメトリックカウントの合計数を与えるように見えます。この例では、「メトリック4」を取得します。このメトリックは、私にいくつの異なるカウントがあるかを示しています。 – Gio

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

userInfoListを想定していますGroupBy()n => n.metric meaフィールドにはUserInfoオブジェクトのすべてからフィールドmetricが取得されます。nのタイプはコンテキストに依存しますが、リストにはUserInfoのオブジェクトが含まれているため、最初に発生するタイプはUserInfoです。 2番目の出現ではnGroupingのオブジェクトのリストなので、タイプGroupingです。

Groupingには、.Count(),などの拡張メソッドがあり、他にも期待できるものがあります。 string.Lenghtを確認するのと同じように、グループで.Count()を確認することができます。