groupbyおよびcountを使用したLINQ


221

これはかなり単純ですが、私は途方に暮れています:このタイプのデータセットを考えると:

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 ..)でカウントされる合計回数とともに一覧表示するテーブルを取得したいと思います。したがって、このセットからは次のようになります。

0 3    
1 2    
2 2    
3 1

私はLINQ構文に取り組んでいますが、groupbyを配置してカウントする場所に行き詰まっています。

POST Edit:投稿された回答が常に機能するようにすることはできませんでした。彼らは常に、異なるカウント数の1つのレコードを返していました。ただし、機能するLINQ to SQLの例をまとめることができました。

        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を一般に初めて使用します。訓練を受けていないこの目には、このアプローチは純粋なLINQアプローチと非常によく似ていますが、別の答えを出しました。


はい私は持っていますが、ジミーの説明は私をさらに助けました。しかし、私は彼の例を機能させることができなかったが、それは私を新しい方向に導いた。
Gio

@Jimmyは、標準のLINQクエリ構文ではなく、LINQ式の関数構文を使用し、さらに、遅延実行形式ではなく、それらの関数の即時実行を示すことにしました。混乱する新しい人のために。彼がそれをした理由がわからない。
リチャードロバートソン

回答:


394

を呼び出した後GroupBy、一連のグループを取得しますIEnumerable<Grouping>。各Grouping自体がKey、グループの作成に使用されたものを公開IEnumerable<T>し、元のデータセット内のアイテムのどれでもあります。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 => info.metric)」に少し問題があります。

class次のようなリスト/配列がすでにあると思います

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

するとdata.GroupBy(x => x.metric)、「xによって定義されたIEnumerableの各要素について、それをdata計算.metricし、同じメトリックを持つすべての要素をaにグループ化し、結果のすべてのグループのGroupingを返しIEnumerableます。

    <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の後で次の結果になります。

(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]

これは素晴らしく素早い返信でしたが、最初の行、具体的には「data.groupby(info => info.metric)」に少し問題があります。明らかに「data」は現在のデータセットですが、「info.metric」は何を再設定しますか?クラス定義?
Gio

「info.metric」は、質問で言及したUserInfoクラスのメトリックプロパティ/フィールドになります。
lee-m

1
おかげでわかりましたが、実際にはこれは私に単一の値、つまり異なるメトリックカウントの総数を与えるようです。この例では、「メトリック4」を取得します。これは、自分が持っているさまざまなカウントの数を示しています。
Gio

1
ワオ。グループ化を完全に説明しました!! それだけで投稿の価値がありました。「メトリックス4」の結果が得られるまでですが、ありがとうございました。
Gio

4
この回答の開始、「GroupByを呼び出した後、一連のグループIEnumerable <Grouping>を取得します。各Grouping自体がグループの作成に使用されるキーを公開し、また、元のデータにあるアイテムのIEnumerable <T>でもあります。セット」は、LINQ GroupByの最も明確な説明です。これまでに読んだことはありませんが、ありがとうございます。
dumbledad 2014年

48

と仮定するuserInfoListList<UserInfo>

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

のラムダ関数はGroupBy()、遭遇したすべてのオブジェクトからn => n.metricフィールドを取得することを意味します。種類は、それはタイプのですが最初に出現して、コンテキストに応じているリストが含まれているため、オブジェクトを。2番目のオカレンスのタイプはです。これは、オブジェクトのリストだからです。metricUserInfonUserInfoUserInfonGroupingGrouping

Groupingには、のような拡張メソッドがあり.Count().Key()期待する他のほとんどすべてのものがあります。あなたがチェックするのと同じよう.Lenghtstring、あなたは確認することができます.Count()グループに。


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

1
小さなタイプミス-> group.keySelect(...)内である必要がありますgroup.Key
Jan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.