Как совместить два словаря без зацикливания? - PullRequest
45 голосов
/ 03 апреля 2009

У меня есть два словаря типа <string,object> в C #. Как я могу скопировать все содержимое одного объекта Dictionary в другой без применения цикла?

Ответы [ 4 ]

90 голосов
/ 03 апреля 2009
var d3 = d1.Concat(d2).ToDictionary(x => x.Key, x => x.Value);
42 голосов
/ 03 апреля 2009

Вы можете использовать Concat:

Dictionary<string, object> d1 = new Dictionary<string, object>();
d1.Add("a", new object());
d1.Add("b", new object());
Dictionary<string, object> d2 = new Dictionary<string, object>();
d2.Add("c", new object());
d2.Add("d", new object());

Dictionary<string, object> d3 = d1.Concat(d2).ToDictionary(e => e.Key, e => e.Value);

foreach (var item in d3)
{
    Console.WriteLine(item.Key);
}
9 голосов
/ 03 апреля 2009

Прежде всего, это невозможно без циклов. Независимо от того, выполняется ли этот цикл в методе (расширения), он все еще требует цикла.

На самом деле я собираюсь рекомендовать делать это вручную. Для всех остальных приведенных ответов необходимо использовать два метода расширения (Concat - ToDictionary и SelectMany - ToDictionary) и, таким образом, выполнить цикл дважды. Если вы делаете это для оптимизации вашего кода, будет быстрее сделать цикл над словарем B и добавить его содержимое в словарь A.

Редактировать: После дальнейшего исследования операция Concat будет выполняться только во время вызова ToDictionary, но я все же думаю, что пользовательский метод расширения будет более эффективным.

Если вы хотите уменьшить размер кода, просто создайте метод расширения:

public static class DictionaryExtensions
{
    public static IDictionary<TKey,TVal> Merge<TKey,TVal>(this IDictionary<TKey,TVal> dictA, IDictionary<TKey,TVal> dictB)
    {
        IDictionary<TKey,TVal> output = new Dictionary<TKey,TVal>(dictA);

        foreach (KeyValuePair<TKey,TVal> pair in dictB)
        {
            // TODO: Check for collisions?
            output.Add(pair.Key, Pair.Value);
        }

        return output;
    }
}

Затем вы можете использовать его, импортировав («используя») пространство имен DictionaryExtensions и написав:

IDictionary<string,objet> output = dictA.Merge(dictB);

Я заставил метод вести себя так, как будто объекты неизменны, но вы можете легко изменить его, чтобы он не возвращал новый словарь и просто сливался в dictA.

5 голосов
/ 03 апреля 2009
var result = dictionaries.SelectMany(dict => dict)
             .ToDictionary(pair => pair.Key, pair => pair.Value);
...