Jak uzyskać wartości z IGrouping

211

Mam pytanie IGroupingi Select()metodę.

Powiedzmy, że mam IEnumerable<IGrouping<int, smth>>w ten sposób:

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

gdzie listjest List<smth>.

A teraz muszę IGroupingw jakiś sposób przekazać wartości każdej z nich na inną listę:

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

Czy ktoś może zasugerować, jak uzyskać wartości ( List<smth>) z IGrouping<int, smth>takiego kontekstu?

Illia Ratkevych
źródło
Identyfikator jest zwykle polem tożsamości, które powinno być unikalne, co uczyniłoby z niego grupowanie bezużytecznym, jeśli tylko próbujesz usunąć zduplikowane dane, zamiast tego spróbuj Distinct (). gdyby była list.GroupBy (x => x.SubID), wówczas sensowne byłoby użycie grupowania, ale w takim przypadku najprawdopodobniej chciałbyś zachować grupowanie i foreach (var grp in groups) {grp.ToList () ; } zrobiłby to
MikeT

Odpowiedzi:

277

Ponieważ IGrouping<TKey, TElement>narzędzia są używane IEnumerable<TElement>, możesz SelectManypołączyć wszystkie elementy IEnumerablesw jedno 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();
Matt Smith
źródło
3
Czy to nie to samo, co zwykłe „zamówienie”? List <smth> newList = list .OrderBy (x => x.id) .ToList ();
MorgoZ
@ MorgoZ, pytanie dotyczy wzięcia groupsi powrotu do płaskiej listy.
Matt Smith
3
@ MorgoZ, OrderBy(x => x.id)posortuje je w porządku rosnącym według identyfikatora. Porównaj to z .GroupBy(x => x.id).SelectMany(group => group), co posortuje je według kolejności pierwszego pojawienia się ID. Jeśli oryginalne identyfikatory są w kolejności: [1,3,2,2,2,3,0], wówczas grupowanie ich, a następnie spłaszczanie na jednej liście spowoduje umieszczenie identyfikatorów w nowej kolejności: [1,3,3, 2,2,2,0].
Pi Fisher
2
Dla mnie to nie działa .. mówi, że tego typu nie można wywnioskować z użycia
Revious
3
typ nie może być wywnioskowany na podstawie użycia
Leo Gurdian
34
foreach (var v in structure) 
{     
    var group = groups.Single(g => g.Key == v. ??? );
    v.ListOfSmth = group.ToList();
}

Najpierw musisz wybrać żądaną grupę. Następnie możesz użyć ToListmetody z grupy. Jest IGroupingto jedna IEnumerablez wartości.

Tim Cools
źródło
17

Bardziej wyjaśniona wersja powyższych odpowiedzi:

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;
    }
}
Bronek
źródło
Nie sądzę, przynajmniej na razie.
snr
15

Z definicji IGrouping:

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

możesz po prostu iterować takie elementy:

IEnumerable<IGrouping<int, smth>> groups = list.GroupBy(x => x.ID)
foreach(IEnumerable<smth> element in groups)
{
//do something
}
użytkownik1275513
źródło
1
który iteruje przez, nie grupuje pozycji w grupie
MikeT
1
O mój błąd, więc: „foreach (smth p in groups.SelectMany (sth => sth))”
użytkownik1275513,