101 votes

Créer un dictionnaire sur une liste avec regroupement

J'ai l'objet suivant dans une liste :

public class DemoClass
{
    public int GroupKey { get; set; }
    public string DemoString { get; set; }
    public object SomeOtherProperty { get; set; }
}

Maintenant, je veux créer le dictionnaire suivant à partir de celui-ci :

Dictionary<int, List<DemoClass>>

Je veux regrouper les List<DemoClass> par la propriété GroupKey mais je ne comprends pas comment cela se passe et j'ai besoin d'aide.

Après avoir réfléchi un peu, j'ai obtenu le comportement souhaité avec :

var groupedDemoClasses = from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                            group demoClass by demoClass.GroupKey
                            into groupedDemoClass
                            select groupedDemoClass;
var neededDictionary = groupedDemoClass.ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

mais, y a-t-il un moyen de transformer cela en une seule déclaration ?

190voto

Jon Skeet Points 692016

Juste pour faire suggestion de mquander béton :

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .GroupBy(x => x.GroupKey)
                             .ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

Vous le rendriez plus court si vous utilisiez des noms de variables plus courts aussi, bien sûr :)

Toutefois, puis-je suggérer qu'un Consulter le site pourrait être plus approprié ? Une Lookup est fondamentalement un dictionnaire d'une clé à une IEnumerable<T> - à moins que vous ne soyez vraiment besoin de les valeurs sous forme de liste, cela rend le code encore plus court (et plus efficace) avec l'option ToLookup appeler :

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .ToLookup(x => x.GroupKey);

84voto

Prashant Points 4362
var groupedDemoClasses = (from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                          group demoClass by demoClass.GroupKey
                          into groupedDemoClass
                          select groupedDemoClass).ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

Celui-ci va fonctionner ! !!

6voto

mquander Points 32650

Tu l'as déjà fait en une ligne. Mets juste le ToDictionary à la fin de votre première ligne. Si vous voulez qu'elle soit plus courte, utilisez la syntaxe de composition fonctionnelle au lieu de la syntaxe de requête.

3voto

Mark Points 5924

Je vais légèrement Hors sujet, mais j'ai trouvé ce fil de discussion parce que je cherchais un moyen de créer un dictionnaire d'un dictionnaire en Linq, et la conversation ici m'a conduit à la réponse...

Usted peut utiliser linq pour créer des dictionnaires multi-niveaux, ce qui est utile pour les scénarios où vous avez plus d'une clé ou d'une dimension sur laquelle vous voulez effectuer une recherche. L'astuce consiste à créer un regroupement, puis à le convertir en dictionnaire, comme suit :

  Dim qry = (From acs In ActualSales _
             Group By acs.ProductID Into Group _
             Select ProductID, Months = Group.ToDictionary(Function(c) c.Period) _
            ).ToDictionary(Function(c) c.ProductID)

La requête qui en résulte peut être utilisée comme suit :

 If qry.ContainsKey(_ProductID) Then
      With qry(_ProductID)
          If .Months.ContainsKey(_Period) Then
             ...
          End If
      End With
 End If

J'espère que cela sera utile à tous ceux qui ont besoin de ce genre d'informations.

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