2009-06-02 5 views
86

Je l'objet suivant dans une liste:Créer un dictionnaire sur une liste avec le regroupement

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

Maintenant, je veux créer suivant dictionnaire sortir:

Dictionary<int, List<DemoClass>> 

Je veux groupe le List<DemoClass> par la propriété GroupKey, mais je ne comprends pas comment cela est fait et de l'aide.

Après avoir réfléchi un peu, j'ai obtenu le comportement nécessaire 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, est-il un moyen de faire cela en une seule déclaration?

Répondre

78
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 !!!

6

Vous en avez déjà fait un monolithe. Il suffit de mettre le ToDictionary à la fin de votre première ligne. Si vous voulez qu'il soit plus court, utilisez la syntaxe de composition fonctionnelle au lieu de la syntaxe de la requête.

170

Juste pour faire mquander's suggestion béton:

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

Tu ferais plus court si vous utilisez des noms de variables plus courts aussi, bien sûr :)

Cependant, je suggérer que Lookup pourrait être plus approprié? Une recherche est essentiellement un dictionnaire à partir d'une clé à un IEnumerable<T> - à moins que vous avez vraiment besoin les valeurs en tant que liste, il rend le code encore plus court (et plus efficace) avec l'appel ToLookup:

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

Je pensais que la recherche n'est pas très bonne, comparé à un dictionnaire construit, dans un environnement à long terme, car il construit le résultat frais pour chaque demande ... s'il vous plaît corrigez-moi, si je me trompe! –

+0

Non, cela crée toute la recherche. En général, ToXXX n'utilise pas l'exécution différée. –

+1

(Vous pensez peut-être à un Groupement, qui est en effet différé.) –

2

Je m va légèrement hors sujet, mais je suis arrivé à ce fil becausde je cherchais un moyen de créer un dictionnaire d'un dictionnaire dans LINQ, et la conversation ici me conduire à la réponse ...

Vous pouvez utiliser linq pour créer des dictionnaires à plusieurs niveaux, ce qui est utile pour scénarios où vous avez plus de 1 clé ou dimension que vous souhaitez rechercher. L'astuce consiste à créer un groupe et puis le convertir en un 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 résultant peut être utilisé comme suit:

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

Espérons que cela est utile à quelqu'un d'autre qui a besoin ce genre de requête.

Questions connexes