Comment obtenir des valeurs de IGrouping


211

J'ai une question sur IGroupingla Select()méthode.

Disons que j'en ai un IEnumerable<IGrouping<int, smth>>de cette façon:

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

listest a List<smth>.

Et maintenant, je dois passer les valeurs de chacun IGroupingà une autre liste d'une manière ou d'une autre:

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

Quelqu'un peut-il suggérer comment obtenir les valeurs ( List<smth>) d'un IGrouping<int, smth>dans un tel contexte?


L'ID est généralement un champ d'identité qui doit être unique, ce qui rendrait le regroupement inutile, si vous essayez simplement de supprimer les données en double, essayez plutôt Distinct (). si c'était list.GroupBy (x => x.SubID) alors il serait logique d'utiliser le groupement mais dans ce cas vous voudrez probablement garder le groupement et foreach (var grp dans les groupes) {grp.ToList () ; } ferait ça
MikeT

Réponses:


277

Depuis les IGrouping<TKey, TElement>implémentations IEnumerable<TElement>, vous pouvez utiliser SelectManypour mettre tout le IEnumerablesdos en un IEnumerabletout:

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
N'est-ce pas la même chose qu'un "orderBy" normal? List <smth> newList = list .OrderBy (x => x.id) .ToList ();
MorgoZ

@MorgoZ, la question est de prendre le groupset de revenir à une liste plate.
Matt Smith

3
@MorgoZ, les triera OrderBy(x => x.id)par ordre croissant par ID. Comparez cela avec .GroupBy(x => x.id).SelectMany(group => group), qui les triera par ordre de première apparition d'ID. Si les ID d'origine sont dans l'ordre: [1,3,2,2,2,3,0], puis en les regroupant puis en les aplatissant dans une seule liste, les ID seront placés dans le nouvel ordre: [1,3,3, 2,2,2,0].
Pi Fisher

2
Ça ne marche pas pour moi .. ça dit que le type ne peut pas être déduit par l'usage
Revious

3
le type ne peut pas être déduit par l'utilisation
Leo Gurdian

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

Vous devez d'abord sélectionner le groupe souhaité. Ensuite, vous pouvez utiliser la ToListméthode de sur le groupe. C'est IGroupingune IEnumerabledes valeurs.


17

Version plus clarifiée des réponses ci-dessus:

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

Je ne pense pas, du moins pour l'instant.
snr

15

De la définition de IGrouping:

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

vous pouvez simplement parcourir des éléments comme celui-ci:

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

1
qui itère à travers il ne groupe pas les éléments du groupe
MikeT

1
Oh mon erreur, alors: 'foreach (smth p dans les groupes.SelectMany (sth => sth))'
user1275513
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.