Compte tenu des performances des recherches et des suppressions de clés de dictionnaire car ce sont des opérations de hachage, et compte tenu du libellé de la question était la meilleure façon, je pense que ci-dessous est une approche parfaitement valide, et les autres sont un peu trop compliqués, à mon humble avis.
public static void MergeOverwrite<T1, T2>(this IDictionary<T1, T2> dictionary, IDictionary<T1, T2> newElements)
{
if (newElements == null) return;
foreach (var e in newElements)
{
dictionary.Remove(e.Key); //or if you don't want to overwrite do (if !.Contains()
dictionary.Add(e);
}
}
OU si vous travaillez dans une application multithread et que votre dictionnaire doit de toute façon être sûr pour les threads, vous devriez faire ceci:
public static void MergeOverwrite<T1, T2>(this ConcurrentDictionary<T1, T2> dictionary, IDictionary<T1, T2> newElements)
{
if (newElements == null || newElements.Count == 0) return;
foreach (var ne in newElements)
{
dictionary.AddOrUpdate(ne.Key, ne.Value, (key, value) => value);
}
}
Vous pouvez ensuite envelopper cela pour lui permettre de gérer une énumération de dictionnaires. Quoi qu'il en soit, vous regardez environ ~ O (3n) (toutes les conditions étant parfaites), car .Add()
cela fera un autre, inutile mais pratiquement gratuit, Contains()
dans les coulisses. Je ne pense pas que ça va beaucoup mieux.
Si vous souhaitez limiter les opérations supplémentaires sur les grandes collections, vous devez résumer le Count
dictionnaire de chaque que vous êtes sur le point de fusionner et définir la capacité du dictionnaire cible à celle-ci, ce qui évite le coût ultérieur du redimensionnement. Donc, le produit final est quelque chose comme ça ...
public static IDictionary<T1, T2> MergeAllOverwrite<T1, T2>(IList<IDictionary<T1, T2>> allDictionaries)
{
var initSize = allDictionaries.Sum(d => d.Count);
var resultDictionary = new Dictionary<T1, T2>(initSize);
allDictionaries.ForEach(resultDictionary.MergeOverwrite);
return resultDictionary;
}
Notez que j'ai utilisé un IList<T>
pour cette méthode ... principalement parce que si vous en utilisez un IEnumerable<T>
, vous vous êtes ouvert à plusieurs énumérations du même ensemble, ce qui peut être très coûteux si vous obtenez votre collection de dictionnaires d'un LINQ différé déclaration.
dicA.Concat(dicB).ToDictionary(kvp => kvp.Key, kvp => kvp.Value)