Объединение двух словарей с дублирующимися ключами с помощью linq - PullRequest
13 голосов
/ 01 августа 2011

Как объединить 2 словаря IDictionary<Guid, MyObject>, где MyObject - это экземпляр класса?

IDictionary<Guid, MyObject> d1 = new Dictionary<Guid, MyObject>();
d1.Add(guid1, m1);
d1.Add(guid2, m2);
d1.Add(guid3, m3);
IDictionary<Guid, MyObject> d2 = new Dictionary<Guid, MyObject>();
d2.Add(guid2, m2);
d2.Add(guid3, m3);
d2.Add(guid4, m4);
IDictionary<Guid, MyObject> d3 = d1.Union(d2) ???

Что в d3 есть следующие записи:

guid1,m1
guid2,m2
guid3,m3
guid4,m4

Ответы [ 6 ]

15 голосов
/ 01 августа 2011
d1.Concat(d2.Where( x=> !d1.Keys.Contains(x.Key)));
5 голосов
/ 01 августа 2011

d1.Union(d2).GroupBy (kvp => kvp.Key).ToDictionary(kvp => kvp.Key, kvp => kvp.First().Value);, чтобы сделать трюк.

IDictionary<Guid, MyObject> d1 = new Dictionary<Guid, MyObject>();
d1.Add(guid1, m1);
d1.Add(guid2, m2);
d1.Add(guid3, m3);
IDictionary<Guid, MyObject> d2 = new Dictionary<Guid, MyObject>();
d2.Add(guid2, m2);
d2.Add(guid3, m3);
d2.Add(guid4, m4);
IDictionary<Guid, MyObject> d3 = 
   d1.Union(d2).GroupBy (kvp => kvp.Key)
       .ToDictionary (kvp => kvp.Key, kvp => kvp.First ().Value);
1 голос
/ 08 мая 2019

Если у вас есть дубликат ключа, вам придется обрабатывать дубликат ключа с помощью оператора where.

var result = d1.Union(d2.Where(k => !d1.ContainsKey(k.Key))).ToDictionary(k => k.Key, v => v.Value)

Примечание: Он не получит дубликат ключа. если будет какой-либо дубликат ключа, он получит ключ d1.

0 голосов
/ 01 августа 2011

Союз выглядит хорошо: http://msdn.microsoft.com/en-us/vcsharp/aa336761.aspx#union1

0 голосов
/ 01 августа 2011

Если дубликатов ключей не существует, для 2 (или более) словарей работает следующее:

var dictionaries = new [] { d1, d2 };
var result = dictionaries.SelectMany(dict => dict)
                     .ToDictionary(pair => pair.Key, pair => pair.Value);
0 голосов
/ 01 августа 2011

Вы можете попробовать что-то вроде

d1.Concat(d2).Distinct(kv => kv.Key).ToDictionary(kv => kv.Key, kv => kv.Value)

Результат concat использует тот факт, что словарь является IEnumerable<KeyvaluePair<Guid,MyObject>>

Поскольку у меня нет компилятора, я только что проверил, что Distinct не может принимать только лямбда-выражения, выбирающие сравниваемое свойство. Однако он может принять EqualityComparer. В проектах я часто использую Generic Equality Comparer, который позволяет передавать лямбды, которые определяют операцию равенства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...