2009-02-17 3 views
27

У меня есть следующий словарь:Как получить все значения словаря <TKey, TValue> как IList <TValue>?

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 в новый список как отдельные элементы списка .... но в этом случае это не совсем то, что мне нужно. Мне просто нужен список всех значений во всем словаре.

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

+1

Я думаю, ваш вопрос, возможно, были доработаны, чтобы сказать: «Я просто хочу список всех элементов в списках, которые содержатся в ключам словаря». Список всех значений в словаре (что вы просили) - это именно то, что вы получали: список списков. –

ответ

39

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

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

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

0

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

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

20

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

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

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

var flattenedList = dict.Values.SelectMany(x => x).ToList(); 
+0

Ах да, я думал, что свойство Values ​​недоступно через интерфейс IDictionary'2. –

44

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

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

dict.Values.ToList(); 
+0

Это сработало для меня – Ziggler

+0

Очень просто, ответ должен быть изменен на это. – rolls

+4

@rolls Нет, потому что 'dict.Values.ToList()' не то же самое, что 'dict.Values.SelectMany (x => x)' последнее приводит к спискам списков, в то время как 'SelectMany' сглаживает и объединяет результирующие списки в одну последовательность. –

 Смежные вопросы

  • Нет связанных вопросов^_^