Как получить все значения словаря <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
Из-за того, как поддерживается словарь (или хеш-таблица), это то, что вы сделали бы. Внутренне реализация содержит ключи, ведра (для обработки столкновений) и значения. Возможно, вы сможете получить список внутренних значений, но вам будет лучше:
IDictionary<int, IList<MyClass>> dict;
var flattenList = dict.SelectMany( x => x.Value );
Он должен сделать трюк;) SelectMany выравнивает результат, что означает, что каждый список объединяется в одну длинную последовательность (IEnumerable`1).
Ответ 2
Заметили, что многие ответы были довольно старыми.
Это также будет работать:
using System.Linq;
dict.Values.ToList();
Ответ 3
Вариант предложения Джона:
var flattenedValues = dict.Values.SelectMany(x => x);
Если вам нужны они в списке, вы можете, конечно, вызвать ToList:
var flattenedList = dict.Values.SelectMany(x => x).ToList();
Ответ 4
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);
Обратите внимание, что это настолько грубо неэффективно, что вы должны снова подумать об использовании словаря для того, чего вы пытаетесь достичь.