我有两个字典(字符串,字符串)。我需要比较这些并创建一个只有Keys不匹配的新词典。例如,给定这些值
Dictionary A
Key Value
=========
A B
C D
Dictionary B
Key Value
=========
A Z
E D
我需要创建一个只有(E,D)
的单个条目的新词典====编辑====
当完成比较时,我只是涉及键,这些值没有意义。键值只是字符串,因此不要链接到其他对象。没有隐藏的映射等。“值”仅在我得到结果字典时才起作用,因为这在我的程序中使用。想想这个问题好像值不存在而我只是想获得字典“B”中的键列表而不是“字典”A中的键列表。我对键“C”不感兴趣我只对字典“B”中的唯一键感兴趣,但对字典“A”中没有感兴趣。
答案 0 :(得分:9)
创建包含B
所有元素的词典,其中的键不在A
中:
var C = B.Where(x => !A.ContainsKey(x.Key))
.ToDictionary(x => x.Key, x => x.Value);
如果您要创建一个字典,其中包含B
的所有元素,其值在A
中,但其键与A
的相应值不匹配,则可以用这个:
var C =
(from a in A
join b in B on a.Value equals b.Value
where a.Key != b.Key
select b)
.ToDictionary(x => x.Key, x => x.Value);
但请注意,如果A
包含两个或更多个键的相同值,则会失败,例如(A, B)
,(C, D)
和(F, D)
。为了解决这个问题,你可以这样做:
var C =
(from a in A
group a by a.Value into g
let a = g.First()
join b in B on a.Value equals b.Value
where a.Key != b.Key
select b)
.ToDictionary(x => x.Key, x => x.Value);
答案 1 :(得分:8)
所以你只想添加第二个字典中不存在于第一个字典中的条目,而不是反之亦然?
var dictC = dictB.Keys.Except(dictA.Keys)
.ToDictionary(bKey => bKey, bKey => dictB[bKey]);
如果你也想要相反,你可以在匿名类型上使用Concat
来使用这种方法:
var dictC = dictB.Keys.Except(dictA.Keys)
.Select(bKey => new{ Key=bKey, Value=dictB[bKey] })
.Concat(dictA.Keys.Except(dictB.Keys)
.Select(aKey => new{ Key=aKey, Value=dictA[aKey] }))
.ToDictionary(kv => kv.Key, kv => kv.Value);
此处不可能存在重复键,因为第一个查询在字典-1中查找不在另一个中的键,而第二个查询查找相反的键。因此,使用Concat
和ToDictionary
安全无误。
答案 2 :(得分:0)
您似乎需要来自字典B
的键值对,其中字典A
具有该值的不同键。在那种情况下,我会做这样的事情:
// sample data
Dictionary<string, string> a = new Dictionary<string, string>();
a.Add("A", "B"); a.Add("C", "D");
Dictionary<string, string> b = new Dictionary<string, string>();
b.Add("A", "Z"); b.Add("E", "D");
// first, reverse dictionary A for simplicity
// to quickly get the key for a value
var revA = a.ToDictionary(kv => kv.Value, kv => kv.Key);
// and then compute the result
var result = b.Where(kv => revA.ContainsKey(kv.Value) && revA[kv.Value] != kv.Key)
.ToDictionary(kv => kv.Key, kv => kv.Value);
这当然假设我们不能在同一个字典中使用不同键映射的值。也就是说,我们不能在同一个字典中使用(A=>B)
和(C=>B)
。我认为这在你的问题中是隐含的。