In Anbetracht der Leistung beim Suchen und Löschen von Wörterbuchschlüsseln da es sich um Hash-Operationen handelt, und da der Wortlaut der Frage am besten Meiner Meinung nach ist der unten stehende Ansatz vollkommen richtig, und die anderen sind meiner Meinung nach etwas zu kompliziert.
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);
}
}
ODER wenn Sie in einer Multithread-Anwendung arbeiten und Ihr Wörterbuch ohnehin thread-sicher sein muss, sollten Sie dies tun:
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);
}
}
Sie könnten dann wrap dies, damit es eine Aufzählung von Wörterbüchern zu behandeln. Unabhängig davon sehen Sie etwa ~O(3n) (alle Bedingungen sind perfekt), da die .Add()
wird eine zusätzliche, unnötige, aber praktisch kostenlose Maßnahme durchgeführt, Contains()
hinter den Kulissen. Ich glaube nicht, dass es noch viel besser wird.
Wenn Sie zusätzliche Operationen bei großen Sammlungen begrenzen wollen, sollten Sie die Count
jedes Wörterbuchs, das Sie zusammenführen wollen, und setzen Sie die Kapazität des Zielwörterbuchs auf diesen Wert, wodurch die späteren Kosten der Größenänderung vermieden werden. Das Endprodukt sieht also etwa so aus...
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;
}
Beachten Sie, dass ich eine IList<T>
zu dieser Methode... vor allem, weil man bei der Aufnahme eines IEnumerable<T>
haben Sie sich für mehrere Aufzählungen desselben Satzes geöffnet, was sehr kostspielig sein kann, wenn Sie Ihre Sammlung von Wörterbüchern aus einer verzögerten LINQ-Anweisung erhalten haben.
238 Stimmen
Unabhängig davon, aber für jeden, der nur zwei Wörterbücher ohne Prüfung auf doppelte Schlüssel zusammenführen möchte, funktioniert dies sehr gut:
dicA.Concat(dicB).ToDictionary(kvp => kvp.Key, kvp => kvp.Value)
8 Stimmen
@Benjol Sie hätten dies im Antwortabschnitt hinzufügen können
8 Stimmen
Clojure's Zusammenführung in C#:
dict1.Concat(dict2).GroupBy(p => p.Key).ToDictionary(g => g.Key, g => g.Last().Value)
7 Stimmen
@Benjol: Beseitigen Sie Duplikate, indem Sie die Einträge aus dem ersten Wörterbuch mit
dictA.Concat(dictB.Where(kvp => !dictA.ContainsKey(kvp.Key))).ToDictionary(kvp=> kvp.Key, kvp => kvp.Value)
.