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?

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

Tim Cools
la source
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;
    }
}
Bronek
la source
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
}
user1275513
la source
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