2015-10-07 2 views
1

У меня есть список элементов, которые я хотел бы группировать по значению свойства. Позже я хотел бы создать diccionary, ключ которого - это значение, которое я использовал для группировки, и значение списка (или IEnumerable) элементов, которые являются каждой группой.Как создать dicctionary из сгруппированных элементов?

Я пытаюсь что-то вроде этого:

Dictionary<long, Ienumerable<MyType>> dic = lstWithElements.GroupBy(x=>x.ID).ToDictionary(x=>x.????) 

Но в методе ToDicrionary не имеют свойство ID. Итак, как я могу создать свой словарь с группируемыми элементами?

Большое вам спасибо.

+1

Вы попробовали x.Key? –

+1

x.Key, FTW ..... – code4life

+0

Можете ли вы включить структуру ввода и вывод, который вы ожидаете? – XtremeBytes

ответ

4

Метод ToDictionary имеет несколько перегрузок, но так как ваш Dictionary использует IEnumerable<MyType> для его Value, вы, вероятно, заинтересованы в overload that accepts two parameters: a key selector, and an element selector.

Dictionary<long, IEnumerable<MyType>> dic = lstWithElements.GroupBy(x=>x.ID).ToDictionary(x=> x.Key, x => x.AsEnumerable()); 
+0

UNFAIR, я сделал перерыв на кофе между написанием ответа, и вы создали правильный ответ в среднее время :) – ipavlu

5

Перегрузка GroupBythat you're using возвращает IEnumerable<IGrouping<long, MyType>>. IGrouping<long, MyType> предоставляет свойство Key типа long, представляющее прогнозируемое значение, с помощью которого элементы были сгруппированы, а также реализует IEnumerable<MyType>.

Итак, по существу, что вам нужно:

var dic = lstWithElements.GroupBy(x => x.ID).ToDictionary(x => x.Key); 

Примечание: Как было отмечено в комментариях, это производит IDictionary<long, IGrouping<long, MyType>>. Это не проблема, поскольку вы только извлекаете элементов из словаря и не пытаетесь добавить новый IEnumerable<MyType> s позже (что кажется маловероятным). Если вам действительно нужен IDictionary<long, IEnumerable<long, MyType>>, используйте код, указанный в this answer.

+1

Это имеет ту же проблему, что и [этот ответ] (https://stackoverflow.com/a/32998068/1187982), что означает, что значения в словаре являются 'IGrouping ', а не' IEnumerable '. –

+1

@JoshuaShearer Да, и с этим нет никаких проблем. Наименее конкретная реализация интерфейса должна определяться потреблением кода, а не испечением в локальные переменные. –

+0

Спасибо за объяснение. Я не думал об этом. Наслаждайтесь своим продвижением. –

1

Попробуйте это:

Dictionary<long, IGrouping<long,MyType>> dic = lstWithElements.GroupBy(x=>x.ID).ToDictionary(x=>x.Key) 
+0

почему голос? –

+0

Это немного избыточно, поскольку попытка получить доступ к значениям любого ключа в словаре дает вам 'IGrouping ', а не 'IEnumerable ', и вы можете получить доступ к элементам 'IGrouping' через свои ключ. Это просто неудобно. –

+1

@JoshuaShearer «IGrouping ' * is * the 'IEnumerable '. Любой потребительский код, ожидающий 'IEnumerable ', с радостью примет 'IGrouping '. В этом коде нет ничего плохого. –

1

I предположим, что ваша структура данных составляет минимум:

class MyType //or struct 
{ 
    long ID; 
}; 

Вы хотите получить список:

List<MyType> list;//with instances of MyType 

либо с различными экземплярами MyType и тот же идентификатор (делает ID неуникальным, не лучший дизайн, возможно,) или некоторые экземпляры в списке несколько раз, то, что кажется лучшим примером, но либо будет работать для заданного вопроса.

Теперь, GroupBy, что он делает? Список

List<MyType> 

превращается в

IEnumerable<MyType> 

затем GroupBy (х => х.ID) группирует и обеспечение:

IEnumerable<IGrouping<long, MyType>> 

таким образом мы получаем элементы

IGrouping<long, MyType> 

Теперь IGrouping знает все IEnumerable делает, наследование интерфейса, плюс он имеет ключ. Так что если вы хотите, чтобы ваш ожидаемый словарю типа:

Dictionary<long,IEnumerable<MyType>> 

вы должны сделать это:

var dictionary = 
list 
.GroupBy(x => x.ID) 
.ToDictionary(x => x.ID, x => x.AsEnumerable()) 
; 

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

x.AsEnumerable() 

как IGrouping наследуется от IEnumerable.

Надеюсь, что это более длинное объяснение поможет :).

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