Подтвердить что ты не робот

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

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

4b9b3361

Ответ 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);

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