LINQ - Перетворення списку на словник зі значенням як список


99

Я маю

List<MyObject> 

що я отримую з бази даних. Однак я хотів би, щоб це було введено властивістю в MyObject для цілей групування. Який найкращий спосіб за допомогою LINQ передати мій список:

Dictionary<long, List<MyObject>>

У мене є таке:

myObjectList.ToDictionary(x => x.KeyedProperty)

Але воно повертається:

Dictionary<long, MyObject>

Ви хочете, щоб словник був закріплений за власністю WHICH MyObject? - у вас їх цілий список ....
Джеймс Керран

Відповіді:


191

Здається, ви хочете згрупувати MyObjectекземпляри за KeyedPropertyі перенести цю групування в Dictionary<long,List<MyObject>>. Якщо так, то спробуйте наступне

List<MyObject> list = ...;
var map = list
  .GroupBy(x => x.KeyedProperty)
  .ToDictionary(x => x.Key, x => x.ToList());

16

Вам слід використовувати ToLookupметод розширення для Enumerableкласу так:

List<MyObject> list = ...;

ILookup<long, MyObject> lookup = list.ToLookup(o => o.KeyedProperty);

Якщо ви хочете помістити це у словник, ви можете скористатися ToDictionaryметодом розширення , наприклад:

IDictionary<long, IEnumerable<MyObject>> dictionary = lookup.ToDictionary(
    l => l.Key);

Яка різниця між цією та прийнятою відповіддю? Чи ILookupзберігає посилання, тоді як прийнята відповідь - ні?
PatPeter

@PatPeter Ідея полягає в тому, що коли у вас є відношення "один до багатьох" між ключем і елементами, a Lookup<TKey, TValue>може бути кращою структурою, ніж a Dictionary<TKey, TValue>.
casperOne

1
@PatPeter, я б сказав, що ILookup - це найкраща структура для використання (як мультимап на карту словника, якщо ви знаєте алгоритми збору C ++), але він має мати на увазі один великий фактор - створений пошук не змінюється. Ви не можете додавати або видаляти записи після цього.
gbjbaanb

Іншим міркуванням є те, що, хоча ILookupце часто є ідеальною структурою коду, вона часто погано обробляється для серіалізації.
Джефф Б,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.