Учитывая производительность поиска и удаления ключей из словаря , так как они являются операциями хэширования, и учитывая, что формулировка вопроса была best , я думаю, что приведенный ниже является совершенно правильным подходом И другие немного сложнее, ИМХО.
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);
}
}
ИЛИ, если вы работаете в многопоточном приложении, и ваш словарь в любом случае должен быть потокобезопасным, вы должны сделать это:
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);
}
}
Затем вы можете обернуть это, чтобы оно обрабатывало перечисление словарей. В любом случае, вы смотрите на ~ O (3n) (все условия идеальны), поскольку .Add()
сделает дополнительное, ненужное, но практически бесплатное, Contains()
за кадром. Я не думаю, что это становится намного лучше.
Если вы хотите ограничить дополнительные операции с большими коллекциями, вы должны суммировать Count
каждого словаря, который вы собираетесь объединить, и установить емкость целевого словаря равной этому, что позволяет избежать более поздних затрат на изменение размера. , Итак, конечный продукт - это что-то вроде этого ...
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;
}
Обратите внимание, что я взял IList<T>
для этого метода ... в основном потому, что если вы берете IEnumerable<T>
, вы открываете себе несколько перечислений одного и того же набора, что может быть очень дорого, если вы получил вашу коллекцию словарей из отложенного оператора LINQ.