web-dev-qa-db-ja.com

Dictionary <TKey、TValue>のすべての値をIList <TValue>として取得するにはどうすればよいですか?

私は次の辞書を持っています:

IDictionary<int, IList<MyClass>> myDictionary 

ディクショナリのすべての値をIListとして取得したい...


どうやってこの状況に陥ったかについての背景を少し付け加えます。

MyClassのリストを取得するメソッドがあります。次に、そのリストを辞書に変換する別のメソッドを用意します。ここで、キーはMyClassのIDです。後で...元のリストにアクセスせずに... MyClassの元のグループ化されていないリストを取得する必要があります。


MyDictionary.Values.ToList()をIListを受け取るメソッドに渡すと、変換できないというコンパイルエラーが発生します。

System.Collections.Generic.List<System.Collections.Generic.IList<MyClass>> 

に:

System.Collections.Generic.IList<MyClass>

これで、IListの各グループが削除され、リストの個別の要素として新しいリストに追加されたことを理解できます。辞書全体のすべての値のリストが必要です。

辞書の各キー値をループし、必要なリストを作成せずに、自分の目的を取得するにはどうすればよいですか?

37
mezoid

辞書(またはハッシュテーブル)がどのように維持されるかにより、これがあなたのすることです。内部的に実装には、キー、バケット(衝突処理用)、および値が含まれます。内部値リストを取得できる場合がありますが、次のようなものの方が優れています。

IDictionary<int, IList<MyClass>> dict;
var flattenList = dict.SelectMany( x => x.Value );

トリックを行う必要があります;)SelectManyは結果をフラット化します。つまり、すべてのリストが1つの長いシーケンス(IEnumerable`1)に連結されます。

47
John Leidegren

多くの答えがかなり古いことに気づきました。

これも機能します:

using System.Linq;

dict.Values.ToList();
74
MrProgram

ジョンの提案のバリエーション:

var flattenedValues = dict.Values.SelectMany(x => x);

リストでそれらが必要な場合は、ToListを呼び出すことができます。

var flattenedList = dict.Values.SelectMany(x => x).ToList();
23
Jon Skeet

Values は、辞書の値を含む ICollection を取得します。辞書の定義からわかるように、ICollection<IList<MyClass>>コレクションとして定義できます。したがって、IList<IList<MyClass>>が本当に必要な場合は、 spacedog のソリューションを使用してください。

本当に必要なのがフラットな「IList」である場合、各値をループする以外に解決策はありません。

IList<MyClass> l=new List<MyClass>();
foreach (IList<MyClass> v in myDictionary.Values)
    l.AddRange(v);

これは非常に非効率的であるため、達成しようとしているものに辞書を使用することをもう一度考える必要があります。

0
Mac