Как получить значения из 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
}
user1275513
источник
1
перебирает группы, а не элементы в группе
MikeT
1
О, моя ошибка, тогда: 'foreach (что-то в группах. Выбирай (sth => sth))'
user1275513