使用linq合并具有重复键的2个词典

时间:2011-08-01 19:13:20

标签: c# linq dictionary merge

如何合并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 个答案:

答案 0 :(得分:15)

d1.Concat(d2.Where( x=> !d1.Keys.Contains(x.Key)));

答案 1 :(得分:5)

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

答案 2 :(得分:1)

如果您有重复键,则必须使用where子句来处理重复键。

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

注意:不会获得重复的密钥。如果有重复的密钥,则得到d1的密钥。

答案 3 :(得分:0)

您可以尝试类似

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

concat的结果使用了字典是IEnumerable<KeyvaluePair<Guid,MyObject>>

这一事实

由于我没有编译器,我只是检查了Distinct不能只接受一个lambda来选择要比较的属性。但是它可以接受EqualityComparer。我在项目中经常使用的是Generic Equality Comparer,允许传入定义相等操作的lambda。

答案 4 :(得分:0)

如果不存在重复键,则以下内容适用于2个(或更多)词典:

var dictionaries = new [] { d1, d2 };
var result = dictionaries.SelectMany(dict => dict)
                     .ToDictionary(pair => pair.Key, pair => pair.Value);

答案 5 :(得分:0)