553 votes

Fusion de dictionnaires en C #

Quelle est la meilleure façon de fusionner 2 dictionnaires ou plus ( Dictionary<T1,T2> ) en C #? (Les fonctionnalités 3.0 comme LINQ vont bien).

Je pense à une signature de méthode semblable à:

 public static Dictionary<TKey,TValue>
                 Merge<TKey,TValue>(Dictionary<TKey,TValue>[] dictionaries);
 

ou

 public static Dictionary<TKey,TValue>
                 Merge<TKey,TValue>(IEnumerable<Dictionary<TKey,TValue>> dictionaries);
 

EDIT: J'ai eu une bonne solution de JaredPar et Jon Skeet, mais je pensais à quelque chose qui gère les clés en double. En cas de collision, peu importe quelle valeur est enregistrée dans la dict si elle est cohérente.

354voto

Jon Skeet Points 692016

Cela dépend en partie de ce que vous voulez arriver si vous avez des doublons. Par exemple, vous pourriez faire:

var result = dictionaries.SelectMany(dict => dict)
                         .ToDictionary(pair => pair.Key, pair => pair.Value);

Qui va exploser si vous avez des doubles des clés.

EDIT: Si vous utilisez ToLookup ensuite, vous aurez une liste de choix qui peuvent avoir plusieurs valeurs pour la clé. Vous pourriez alors que convertir un dictionnaire:

var result = dictionaries.SelectMany(dict => dict)
                         .ToLookup(pair => pair.Key, pair => pair.Value)
                         .ToDictionary(group => group.Key, group => group.First());

C'est un peu moche - et inefficace - mais c'est la façon la plus rapide de le faire en termes de code. (Je n'ai pas testé, certes.)

Vous pouvez écrire votre propre ToDictionary2 méthode d'extension de cours (avec un nom de mieux, mais je n'ai pas le temps de penser à aujourd'hui) - il n'est pas très difficile à faire, il suffit de les écraser (ou ignorant) des doubles des clés. L'important (à mon avis) est à l'aide de SelectMany, et à la réalisation d'un dictionnaire prend en charge une itération sur ses paires clé/valeur.

303voto

Jonas Stensved Points 2803

Je le ferais comme ceci:

 dictionaryFrom.ToList().ForEach(x => dictionaryTo.Add(x.Key, x.Value));
 

Simple et facile. Selon ce blog, c'est encore plus rapide que la plupart des boucles.

Il va bien sûr lancer une exception s'il y a des doublons, donc vous devrez vérifier avant de fusionner.

55voto

orip Points 28225

La solution triviale serait:

 using System.Collections.Generic;
...
public static Dictionary<TKey, TValue>
    Merge<TKey,TValue>(IEnumerable<Dictionary<TKey, TValue>> dictionaries)
{
    var result = new Dictionary<TKey, TValue>();
    foreach (var dict in dictionaries)
        foreach (var x in dict)
            result[x.Key] = x.Value;
    return result;
}
 

26voto

JaredPar Points 333733
Essayez ce qui suit :

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