So erhalten Sie Werte aus IGrouping


210

Ich habe eine Frage zu IGroupingund die Select()Methode.

Nehmen wir an, ich habe eine IEnumerable<IGrouping<int, smth>>auf diese Weise:

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

wo listist ein List<smth>.

Und jetzt muss ich die Werte von jedem IGroupingauf irgendeine Weise an eine andere Liste übergeben:

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

Kann jemand vorschlagen, wie man die Werte ( List<smth>) aus einem IGrouping<int, smth>solchen Kontext erhält ?


ID ist normalerweise ein Identitätsfeld, das eindeutig sein sollte, wodurch die Gruppierung unbrauchbar wird, wenn Sie nur versuchen, doppelte Daten zu entfernen, versuchen Sie stattdessen Distinct (). Wenn es list.GroupBy (x => x.SubID) wäre, wäre es sinnvoll, die Gruppierung zu verwenden, aber in diesem Fall möchten Sie höchstwahrscheinlich die Gruppierung und foreach beibehalten (var grp in groups) {grp.ToList () ;; } würde das tun
MikeT

Antworten:


277

Seit den IGrouping<TKey, TElement>Implementierungen IEnumerable<TElement>können Sie verwenden SelectMany, um den gesamten IEnumerablesRücken zu einem IEnumerablezusammenzufügen:

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
Ist das nicht dasselbe wie ein normaler "orderBy"? List <smth> newList = list .OrderBy (x => x.id) .ToList ();
MorgoZ

@MorgoZ, die Frage ist, die zu nehmen groupsund zu einer flachen Liste zurückzukehren.
Matt Smith

3
@MorgoZ, OrderBy(x => x.id)sortiert sie in aufsteigender Reihenfolge nach ID. Vergleichen Sie dies mit .GroupBy(x => x.id).SelectMany(group => group), wodurch sie nach der Reihenfolge des ersten Auftretens der ID sortiert werden. Wenn die ursprünglichen IDs in der Reihenfolge [1,3,2,2,2,3,0] vorliegen, werden die IDs durch Gruppieren und anschließendes Reduzieren in einer Liste in die neue Reihenfolge gebracht: [1,3,3, 2,2,2,0].
Pi Fisher

2
Es funktioniert nicht für mich .. es sagt, dass der Typ nicht durch die Verwendung abgeleitet werden kann
Revious

3
Typ kann nicht durch die Verwendung abgeleitet werden
Leo Gurdian

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

Zuerst müssen Sie die gewünschte Gruppe auswählen. Dann können Sie die ToListMethode von für die Gruppe verwenden. Das IGroupingist einer IEnumerableder Werte.


17

Klarere Version der obigen Antworten:

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

Das glaube ich zumindest vorerst nicht.
Snr

15

Aus der Definition von IGrouping:

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

Sie können einfach durch folgende Elemente iterieren:

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

1
das iteriert durch er gruppiert nicht die Elemente in der Gruppe
MikeT

1
Oh mein Fehler, dann: 'foreach (smth p in Gruppen. SelectMany (etw => etw))'
user1275513
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.