IGrouping'den değerler nasıl alınır?


211

Bir yöntem IGroupingve Select()yöntem hakkında sorum var .

Diyelim ki IEnumerable<IGrouping<int, smth>>bu şekilde bir var:

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

nerede lista List<smth>.

Ve şimdi her birinin değerlerini IGroupingbaşka bir listeye bir şekilde iletmem gerekiyor:

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

Herkes böyle bir bağlamda List<smth>bir değerlerini ( ) almak için önerebilir miyim IGrouping<int, smth>?


Kimlik genellikle benzersiz olması gereken bir kimlik alanıdır, bu da gruplamayı işe yaramaz hale getirir, sadece yinelenen verileri kaldırmaya çalışıyorsanız bunun yerine Distinct () öğesini deneyin. list.GroupBy (x => x.SubID) olsaydı, gruplamayı kullanmak mantıklı olurdu, ancak bu durumda büyük olasılıkla gruplamayı ve foreach'u (gruplarda var grp) tutmak istersiniz {grp.ToList () ; } bunu yapar
MikeT

Yanıtlar:


277

Yana IGrouping<TKey, TElement>uygular IEnumerable<TElement>, kullanabileceğiniz SelectManytüm koymak için IEnumerablesiçine geri IEnumerablehep birlikte:

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
Bu normal bir "orderBy" ile aynı değil mi? Liste <smth> newList = list .OrderBy (x => x.id) .ToList ();
MorgoZ

@MorgoZ, soru groupsalmak ve düz bir listeye geri dönmekle ilgilidir .
Matt Smith

3
@MorgoZ, OrderBy(x => x.id)bunları kimliğe göre artan sırada sıralayacaktır. Bunu .GroupBy(x => x.id).SelectMany(group => group), kimliğin ilk ortaya çıkış sırasına göre sıralayacak olan ile karşılaştırın. Orijinal kimlikler şu sıradaysa: [1,3,2,2,2,3,0], bunları gruplandırıp bir liste halinde düzleştirmek, kimlikleri yeni sıraya yerleştirir: [1,3,3, 2,2,2,0].
Pi Fisher

2
Benim için çalışmıyor .. bu tür kullanım tarafından çıkarılamaz diyor
Revious

3
türü kullanım tarafından çıkarılamaz
Leo Gurdian

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

İlk önce istenen grubu seçmeniz gerekir. Sonra ToListgrup üzerinde yöntemini kullanabilirsiniz . IGroupingA, IEnumerabledeğerler.


17

Yukarıdaki cevapların daha açık bir versiyonu:

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;
    }
}

En azından şimdilik öyle düşünmüyorum.
snr

15

IGrouping tanımından:

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

sadece bunun gibi unsurları tekrarlayabilirsiniz:

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

1
gruptaki öğeleri değil, o gruplar aracılığıyla
yineliyor

1
Ah benim hatam, o zaman: 'foreach (gruplar halinde ikramiye.SelectMany (sth => sth))'
user1275513
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.