Considerando o desempenho das pesquisas e exclusões de chaves do dicionário, pois são operações de hash, e considerando que a redação da pergunta era a melhor maneira, acho que abaixo é uma abordagem perfeitamente válida, e as outras são um pouco complicadas demais, 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);
}
}
OU se você estiver trabalhando em um aplicativo multithread e seu dicionário precisar ser seguro para threads de qualquer maneira, faça o seguinte:
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);
}
}
Em seguida, você pode agrupar isso para fazer com que ele lide com uma enumeração de dicionários. Independentemente disso, você está olhando para ~ O (3n) (todas as condições são perfeitas), já que .Add()
ele fará um adicional, desnecessário, mas praticamente gratuito Contains()
nos bastidores. Eu não acho que fica muito melhor.
Se você deseja limitar operações extras em coleções grandes, você deve resumir o Count
de cada dicionário que você está prestes a mesclar e definir a capacidade do dicionário de destino para isso, o que evita o custo posterior de redimensionamento. Então, o produto final é algo como isto ...
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;
}
Observe que eu adotei um IList<T>
método nesse método ... principalmente porque se você IEnumerable<T>
usar um , você se abriu para várias enumerações do mesmo conjunto, o que pode ser muito caro se você tiver sua coleção de dicionários de um LINQ adiado declaração.
dicA.Concat(dicB).ToDictionary(kvp => kvp.Key, kvp => kvp.Value)