Teniendo en cuenta el rendimiento de las búsquedas y eliminaciones de claves del diccionario, ya que son operaciones hash, y teniendo en cuenta la redacción de la pregunta fue la mejor manera, creo que a continuación es un enfoque perfectamente válido, y los otros son un poco demasiado complicados, en mi humilde opinión.
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);
}
}
O bien, si está trabajando en una aplicación multiproceso y su diccionario debe ser seguro para subprocesos de todos modos, debería hacer esto:
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);
}
}
Luego, podría ajustar esto para que maneje una enumeración de diccionarios. De todos modos, estás viendo aproximadamente ~ O (3n) (todas las condiciones son perfectas), ya .Add()
que harán un Contains()
detrás de escena adicional, innecesario pero prácticamente gratis . No creo que mejore mucho.
Si desea limitar las operaciones adicionales en colecciones grandes, debe resumir el Count
de cada diccionario que está a punto de fusionar y establecer la capacidad del diccionario de destino, lo que evita el costo posterior de cambiar el tamaño. Entonces, el producto final es algo como esto ...
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;
}
Tenga en cuenta que acepté IList<T>
este método ... sobre todo porque si acepta un IEnumerable<T>
, se ha abierto a múltiples enumeraciones del mismo conjunto, lo que puede ser muy costoso si obtiene su colección de diccionarios de un LINQ diferido declaración.
dicA.Concat(dicB).ToDictionary(kvp => kvp.Key, kvp => kvp.Value)