287 votes

Comment obtenir des valeurs d'IGrouping

J'ai une question sur IGrouping et le Select() méthode.

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

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

list est un List<smth> .

Et maintenant je dois passer les valeurs de chaque 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 ?

0 votes

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

352voto

Matt Smith Points 6843

Desde IGrouping<TKey, TElement> met en œuvre IEnumerable<TElement> vous pouvez utiliser SelectMany pour mettre tous les IEnumerables en un seul IEnumerable tous ensemble :

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();

Voici un exemple qui se construit et s'exécute : https://dotnetfiddle.net/DyuaaP

Commentaire vidéo de cette solution : https://youtu.be/6BsU1n1KTdo

5 votes

N'est-ce pas la même chose qu'un "orderBy" normal ? Liste<smth> newList = list .OrderBy(x => x.id).ToList() ;

0 votes

@MorgoZ, la question porte sur la prise en charge de la groups et revenir à une liste plate.

4 votes

@MorgoZ, OrderBy(x => x.id) les triera dans l'ordre croissant par ID. Comparez cela avec .GroupBy(x => x.id).SelectMany(group => group) qui les triera par ordre de première apparition de l'ID. Si les ID originaux sont dans l'ordre : [1,3,2,2,2,3,0], le fait de les regrouper puis de les aplatir en une seule liste placera les ID dans le nouvel ordre : [1,3,3,2,2,2,0].

48voto

Tim Cools Points 565
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 le bouton ToList méthode de sur le groupe. Le site IGrouping est un IEnumerable des valeurs.

0 votes

Cette réponse est correcte, mais je pense que la question est déjà fausse. Pourquoi convertir votre IEnumerable<smth> à un List<smth> en premier lieu ?

26voto

Bronek Points 1476

Version plus claire 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;
    }
}

18voto

user1275513 Points 19

D'après la définition de IGrouping :

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

vous pouvez simplement itérer à travers les éléments comme ceci :

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

4 votes

Qui itère sur les groupes et non sur les éléments du groupe.

3 votes

Oh, je me suis trompé, alors : "foreach (smth p in groups.SelectMany(sth => sth))

1 votes

Google montre de nombreux exemples comme celui-ci, où l'énumération est effectuée par une boucle foreach. Mais la question était de savoir comment obtenir la liste d'éléments elle-même.

10voto

SA- Points 73
var groups = list.GroupBy(x => x.ID);

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

"IGrouping<int, smth> group" est en fait un IEnumerable avec une clé, donc soit :

  • itérer sur le groupe ou
  • utiliser group.ToList() pour le convertir en une Liste

    foreach (IGrouping<int, smth> group in groups) { var thisIsYourGroupKey = group.Key; List<smth> list = group.ToList(); // or use directly group.foreach }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X