In Anbetracht der performance of dictionary key lookups and deletes da sie Hash-Operationen, und war die Formulierung der Frage unter Berücksichtigung besten Art und Weise, ich glaube, unten, dass ein absolut gültige Ansatz ist, und die anderen sind ein bisschen zu kompliziert, IMHO .
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 und das Wörterbuch muss arbeiten Thread-sicher sowieso sein, 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 diese wickeln, um es zu behandeln ein Aufzählung von Wörterbüchern. Unabhängig davon, Sie betrachten ~ O (3n) (alle Bedingungen sind perfekt), da die .Add()
eine zusätzliche, unnötige, aber praktisch frei, Contains()
hinter den Kulissen tun wird. Ich denke nicht, dass es viel besser wird.
Wenn Sie zusätzliche Operationen für große Sammlungen einschränken möchten, sollten Sie die Count
jedes Wörterbuchs, das Sie zusammenführen möchten, zusammenfassen und die Kapazität des Zielwörterbuchs auf diese festlegen, wodurch die späteren Größenanpassungen vermieden werden. So ist Endprodukt so etwas wie dieses ...
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;
}
Bitte beachte, dass ich in einem IList<T>
dieser Methode nahm ... vor allem, weil, wenn Sie in einem IEnumerable<T>
nehmen, können Sie sich geöffnet haben bis zu mehreren Aufzählungen Dieselbe Menge, die sehr teuer sein kann, wenn Sie Ihre Sammlung von Wörterbüchern aus einer zurückgestellten LINQ-Anweisung erhalten.
Nicht verwandt, aber für jeden, der nur zwei Wörterbücher ohne doppelte Schlüsselüberprüfungen zusammenführen möchte, funktioniert dies gut: 'dicA.Concat (dicB). ToDictionary (kvp => kvp.Key, kvp => kvp.Value)' – Benjol
@ Benjol, Sie könnten dies in Antwort Abschnitt hinzugefügt haben –
Clojure Merge in C#: 'dict1.Concat (dict2) .GroupBy (p => p.Key). ToDictionary (g => g.Key, g => g.Last() .Wert) ' – Bruce