グループ化されたリストに辞書を作成する


106

リストに次のオブジェクトがあります。

public class DemoClass
{
    public int GroupKey { get; set; }
    public string DemoString { get; set; }
    public object SomeOtherProperty { get; set; }
}

ここで、次の辞書を作成します。

Dictionary<int, List<DemoClass>>

List<DemoClass>プロパティごとにグループ化したいのですが、GroupKeyこれがどのように行われるのか、いくつかのヘルプがわかりません。

少し考えた後、私は必要な行動を達成しました:

var groupedDemoClasses = from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                            group demoClass by demoClass.GroupKey
                            into groupedDemoClass
                            select groupedDemoClass;
var neededDictionary = groupedDemoClass.ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

しかし、これを単一のステートメントにする方法はありますか?

回答:


88
var groupedDemoClasses = (from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                          group demoClass by demoClass.GroupKey
                          into groupedDemoClass
                          select groupedDemoClass).ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

これは動作します!!!


198

マカンダーの提案を具体化するためだけに:

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .GroupBy(x => x.GroupKey)
                             .ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

もちろん、短い変数名も使用している場合は短くします:)

しかし、ルックアップの方が適切かもしれないと私は提案するでしょうか?Lookupは基本的にキーからへのディクショナリIEnumerable<T>です。値をリストとして本当に必要としない限り、ToLookup呼び出しでコードがさらに短く(効率的に)なります。

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .ToLookup(x => x.GroupKey);

1
長期的な環境では、構築されたディクショナリーと比較して、ルックアップのパフォーマンスはそれほど良くないと考えました。なぜなら、すべての要求に対して結果が新鮮になるためです...もし間違っていたら修正してください!
Andreas Niedermair

いいえ、検索全体を作成します。一般に、ToXXXは遅延実行を使用しません。
Jon Skeet、

1
(実際に延期されているグループ化について考えているかもしれません。)
Jon Skeet

1
私がそんなに意地悪でなかったら私はあなたを投票するでしょう。Linqに来て、聞いたこともないデータ構造に留まりました!
Chris McCall、

2
@sasikt:モデルは何でも検索できるというもので、キーが存在しない場合は空のコレクションを取得するだけです。これは、多くの場合、TryGetValueアプローチのIMOよりも便利です。
Jon Skeet

6

あなたはすでにそれをワンライナーにしました。ToDictionary最初の行の終わりにを置くだけです。短くしたい場合は、クエリ構文の代わりに関数合成構文を使用してください。


3

私は行くよ少しここでオフトピックが、私はLINQの辞書の辞書を作成する方法を探していた、とここで会話が答えに私を導くbecausde私はこのスレッドになりました...

あなたはできるあなたがで検索すること以上1つのキーまたはディメンションを持っているシナリオに有用である、マルチレベルの辞書を作成するためにLINQを使用しています。トリックは、次のようにグループを作成してから、辞書に変換することです。

  Dim qry = (From acs In ActualSales _
             Group By acs.ProductID Into Group _
             Select ProductID, Months = Group.ToDictionary(Function(c) c.Period) _
            ).ToDictionary(Function(c) c.ProductID)

結果のクエリは次のように使用できます。

 If qry.ContainsKey(_ProductID) Then
      With qry(_ProductID)
          If .Months.ContainsKey(_Period) Then
             ...
          End If
      End With
 End If

これがこの種のクエリを必要とする他の人に役立つことを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.