Как получить значения из IGrouping


211

У меня есть вопрос IGroupingи о Select()методе.

Допустим, у меня есть IEnumerable<IGrouping<int, smth>>таким образом:

var groups = list.GroupBy(x => x.ID);

где listэто List<smth>.

И теперь мне нужно IGroupingкаким-то образом передать значения каждого в другой список:

foreach (var v in structure)
{
    v.ListOfSmth = groups.Select(...); // <- ???
}

Кто-нибудь может подсказать, как получить значения ( List<smth>) из IGrouping<int, smth>в таком контексте?


Идентификатор обычно представляет собой поле идентификации, которое должно быть уникальным, что делает группирование по нему бесполезным, если вы просто пытаетесь удалить дублирующиеся данные, вместо этого попробуйте Distinct (). если бы это был list.GroupBy (x => x.SubID), то имело бы смысл использовать группировку, но в этом случае вы, скорее всего, захотите сохранить группировку и foreach (var grp в группах) {grp.ToList () ; } сделал бы это
MikeT

Ответы:


277

Поскольку IGrouping<TKey, TElement>реализует IEnumerable<TElement>, вы можете использовать, SelectManyчтобы собрать все IEnumerablesобратно в один IEnumerableвсе вместе:

List<smth> list = new List<smth>();
IEnumerable<IGrouping<int, smth>> groups = list.GroupBy(x => x.id);
IEnumerable<smth> smths = groups.SelectMany(group => group);
List<smth> newList = smths.ToList();

3
Разве это не то же самое, что и обычный "orderBy"? List <smth> newList = list .OrderBy (x => x.id) .ToList ();
MorgoZ

@MorgoZ, вопрос в том, чтобы взять groupsи вернуться к единому списку.
Мэтт Смит

3
@MorgoZ, OrderBy(x => x.id)отсортирует их в порядке возрастания по идентификатору. Сравните это с тем .GroupBy(x => x.id).SelectMany(group => group), что отсортирует их по порядку первого появления идентификатора. Если исходные идентификаторы имеют следующий порядок: [1,3,2,2,2,3,0], то при группировании их и сведении в один список идентификаторы будут размещены в новом порядке: [1,3,3, 2,2,2,0].
Пи Фишер

2
Это не работает для меня .. он говорит, что тип не может быть выведен из использования
Revious

3
тип не может быть выведен из использования
Лев Гурдиан

34
foreach (var v in structure) 
{     
    var group = groups.Single(g => g.Key == v. ??? );
    v.ListOfSmth = group.ToList();
}

Сначала нужно выбрать нужную группу. Тогда вы можете использовать ToListметод группы. IGroupingЯвляется IEnumerableзначений.


17

Более уточненная версия приведенных выше ответов:

IEnumerable<IGrouping<int, ClassA>> groups = list.GroupBy(x => x.PropertyIntOfClassA);

foreach (var groupingByClassA in groups)
{
    int propertyIntOfClassA = groupingByClassA.Key;

    //iterating through values
    foreach (var classA in groupingByClassA)
    {
        int key = classA.PropertyIntOfClassA;
    }
}

Я так не думаю, по крайней мере сейчас.
ОСШ

15

Из определения IGrouping:

IGrouping<out TKey, out TElement> : IEnumerable<TElement>, IEnumerable

Вы можете просто перебрать элементы вроде этого:

IEnumerable<IGrouping<int, smth>> groups = list.GroupBy(x => x.ID)
foreach(IEnumerable<smth> element in groups)
{
//do something
}

1
перебирает группы, а не элементы в группе
MikeT

1
О, моя ошибка, тогда: 'foreach (что-то в группах. Выбирай (sth => sth))'
user1275513
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.