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 ?

Illia Ratkevych
quelle
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();
Matt Smith
quelle
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.

Tim kühlt ab
quelle
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;
    }
}
Bronek
quelle
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
}
user1275513
quelle
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