Как получить все значения словаря <TKey, TValue> как IList <TValue>? - PullRequest
36 голосов
/ 17 февраля 2009

У меня есть следующий словарь:

IDictionary<int, IList<MyClass>> myDictionary 

и я хочу получить все значения в словаре как IList ....


Просто добавлю немного фона о том, как я попал в эту ситуацию ...

У меня есть метод, который возвращает мне список MyClass. Затем у меня есть другой метод, который преобразует этот список в словарь, в котором ключом является идентификатор MyClass. Позже ... и без доступа к этому первоначальному списку ... Мне нужно получить исходный разгруппированный список MyClass.


Когда я передаю myDictionary.Values.ToList () в метод, который принимает IList, я получаю ошибку компиляции, которая говорит, что он не может преобразовать из

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

до:

System.Collections.Generic.IList<MyClass>

Теперь я могу понять, что он ушел и добавил каждую группу IList в новый список в качестве отдельных элементов списка ... но в данном случае это не совсем то, что мне нужно. Я просто хочу список всех значений во всем словаре.

Как тогда я могу получить то, что мне нужно, не просматривая каждое из ключевых значений в словаре и создавая нужный мне список?

Ответы [ 4 ]

71 голосов
/ 10 ноября 2015

Заметил, что многие ответы были довольно старыми.

Это также будет работать:

using System.Linq;

dict.Values.ToList();
44 голосов
/ 17 февраля 2009

Из-за того, как ведется словарь (или хеш-таблица), это то, что вы будете делать. Внутренне реализация содержит ключи, сегменты (для обработки коллизий) и значения. Возможно, вы сможете получить внутренний список значений, но вам лучше что-то вроде этого:

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

Это должно сработать;) SelectMany выравнивает результат, что означает, что каждый список объединяется в одну длинную последовательность (IEnumerable`1).

22 голосов
/ 17 февраля 2009

Вариант по предложению Джона:

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

Если они вам нужны в списке, вы, конечно, можете вызвать ToList:

var flattenedList = dict.Values.SelectMany(x => x).ToList();
0 голосов
/ 17 февраля 2009

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);

Обратите внимание, что это настолько неэффективно, что вам следует снова подумать об использовании словаря для того, чего вы пытаетесь достичь.

...