15

How to merge 2 dictionaries of IDictionary<Guid, MyObject> where MyObject is a class instance?

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) ???

That in d3 there are the following entries:

guid1,m1
guid2,m2
guid3,m3
guid4,m4
Mechanical snail
  • 26,499
  • 14
  • 83
  • 107
Chesnokov Yuriy
  • 1,560
  • 5
  • 19
  • 33

6 Answers6

20
d1.Concat(d2.Where( x=> !d1.Keys.Contains(x.Key)));
croxy
  • 3,641
  • 8
  • 25
  • 42
Eric H
  • 1,591
  • 1
  • 10
  • 14
5

d1.Union(d2).GroupBy (kvp => kvp.Key).ToDictionary(kvp => kvp.Key, kvp => kvp.First().Value); out to do the trick.

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);
agent-j
  • 25,367
  • 5
  • 47
  • 76
  • thanks but I tried that and Union leads to Exception with 'An item with the same key has already been added' – Chesnokov Yuriy Aug 01 '11 at 19:32
  • I fixed it. ` IDictionary d3 = d1.Union(d2).GroupBy (kvp => kvp.Key) .ToDictionary (kvp => kvp.Key, kvp => kvp.First ().Value); ` – agent-j Aug 01 '11 at 22:20
  • thank you very much, that works, how that line avoids duplicate keys? is that faster than `d1.Concat(d2.Where(x => !d1.Keys.Contains(x.Key)))`? – Chesnokov Yuriy Aug 02 '11 at 05:27
  • I tested that using Stopwatch, using of Concat is 3 time faster, SO DO NOT USE Union – NET3 Nov 22 '12 at 23:00
1

If you have duplicate key then you'll have to handle duplicate key with the using of where clause.

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

Note : It will not get duplicate key. if there will be any duplicate key than it will get d1's key.

0

You could try something like

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

The result of concat makes use of the fact that the dictionary is an IEnumerable<KeyvaluePair<Guid,MyObject>>

Since I do not have a compiler I just checked that Distinct cannot accept just a lambda selecting the property to be compared. However it can accept an EqualityComparer. What I often have in projects is a Generic Equality Comparer that allows to pass in lambdas which define the equality operation.

flq
  • 20,838
  • 4
  • 49
  • 72
0

When no duplicates keys exist, the following works for 2 (or more) dictionaries:

var dictionaries = new [] { d1, d2 };
var result = dictionaries.SelectMany(dict => dict)
                     .ToDictionary(pair => pair.Key, pair => pair.Value);
Chaim Zonnenberg
  • 1,667
  • 13
  • 9
0

Union looks good: http://msdn.microsoft.com/en-us/vcsharp/aa336761.aspx#union1

Paul Nikonowicz
  • 3,825
  • 18
  • 37