Sélectionnez un dictionnaire <T1, T2> avec LINQ

171

J'ai utilisé le mot clé "select" et la méthode d'extension pour renvoyer un IEnumerable<T>avec LINQ, mais j'ai besoin de renvoyer un générique Dictionary<T1, T2>et je ne peux pas le comprendre. L'exemple que j'ai appris en utilisant quelque chose sous une forme similaire à la suivante:

IEnumerable<T> coll = from x in y 
    select new SomeClass{ prop1 = value1, prop2 = value2 };

J'ai également fait la même chose avec les méthodes d'extension. J'ai supposé que puisque les éléments de a Dictionary<T1, T2>peuvent être itérés, KeyValuePair<T1, T2>je pouvais simplement remplacer "SomeClass" dans l'exemple ci-dessus par " new KeyValuePair<T1, T2> { ...", mais cela ne fonctionnait pas (la clé et la valeur étaient marquées en lecture seule, je ne pouvais donc pas compiler ce code ).

Est-ce possible ou dois-je le faire en plusieurs étapes?

Merci.

Riches
la source

Réponses:

284

Les méthodes d'extensions fournissent également une extension ToDictionary . Il est assez simple à utiliser, l'utilisation générale consiste à passer un sélecteur lambda pour la clé et à obtenir l'objet comme valeur, mais vous pouvez passer un sélecteur lambda pour la clé et la valeur.

class SomeObject
{
    public int ID { get; set; }
    public string Name { get; set; }
}

SomeObject[] objects = new SomeObject[]
{
    new SomeObject { ID = 1, Name = "Hello" },
    new SomeObject { ID = 2, Name = "World" }
};

Dictionary<int, string> objectDictionary = objects.ToDictionary(o => o.ID, o => o.Name);

Puis objectDictionary[1]contiendrait la valeur "Bonjour"

Quintin Robinson
la source
44
var dictionary = (from x in y 
                  select new SomeClass
                  {
                      prop1 = value1,
                      prop2 = value2
                  }
                  ).ToDictionary(item => item.prop1);

Cela suppose que SomeClass.prop1c'est ce que l'on souhaite Keypour le dictionnaire.

Albertein
la source
27
.ToDictionary(item => item.prop1, item => item.prop2);pour explicitement définir la valeur aussi.
finoutlook
42

Une collection de KeyValuePairest encore plus explicite et s'exécute très bien.

Dictionary<int, string> dictionary = objects
    .Select(x=> new KeyValuePair<int, string>(x.Id, x.Name))
    .ToDictionary(x=>x.Key, x=>x.Value);
Antoine Meltzheim
la source
Est-il possible de supprimer .ToDictionary (x => x.Key, x => x.Value); et remplacer le nouveau KeyValuePair par un nouveau dictionnaire?
Amir Hajiha
@ AmirNo-Family Vous vous trompez. La méthode Select (x => x ...) effectue une projection pour chaque élément de la collection d' objets . Donc, remplacer le nouveau KeyValuePair par un nouveau dictionnaire créerait un dictionnaire de dictionnaires. Je ne pense pas que ce soit ce que vous visez.
Antoine Meltzheim
J'ai une liste de Dictionary <string, string> et j'essayais d'utiliser select sur eux mais cela lève une erreur de compilation.
Amir Hajiha