wag*_*ghe 23 .net c# linq dictionary
我的问题被标记为这个问题的可能重复:如何在没有循环的情况下组合两个词典?
我相信我的问题是不同的,因为我问的是如何以特定的方式组合两个词典:我希望Dictionary1中的所有项目加上Dictionary2中不存在的所有项目(即密钥不存在).
我有两个这样的词典:
var d1 = new Dictionary<string,object>();
var d2 = new Dictionary<string,object>();
d1["a"] = 1;
d1["b"] = 2;
d1["c"] = 3;
d2["a"] = 11;
d2["e"] = 12;
d2["c"] = 13;
Run Code Online (Sandbox Code Playgroud)
我想将它们组合成一个新的词典(从技术上讲,它不必是一个字典,它可能只是一个序列KeyValuePairs
),以便输出包含所有KeyValuePairs
来自d1和只有KeyValuePairs,d2
其Key不会出现在d1
.
概念:
var d3 = d1.Concat(d2.Except(d1))
Run Code Online (Sandbox Code Playgroud)
但这给了我d1和d2的所有元素.
似乎它应该是显而易见的,但我必须遗漏一些东西.
Mar*_*ers 36
Except
默认使用时,它使用默认的相等比较器,该KeyValuePair
类型比较键和值.你可以这样做:
var d3 = d1.Concat(d2.Where(kvp => !d1.ContainsKey(kvp.Key)));
Run Code Online (Sandbox Code Playgroud)
嗯,我不知道这是否是 LinQ 中的一个新功能,但这正是.Union()
:
var d3 = d1.Union(d2);
Run Code Online (Sandbox Code Playgroud)
当然,对于字典,您必须提供自定义相等比较器以仅匹配键:
class KeyValuePairComparer<TKey, TValue> : IEqualityComparer<KeyValuePair<TKey, TValue>>
{
public bool Equals(KeyValuePair<TKey, TValue> x, KeyValuePair<TKey, TValue> y)
{
return x.Key.Equals(y.Key);
}
public int GetHashCode(KeyValuePair<TKey, TValue> x)
{
return x.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
进而 :
var d3 = d1.Union(d2, new KeyValuePairComparer<string, object>());
Run Code Online (Sandbox Code Playgroud)
对于您的示例,输出将是(在 C# 交互中测试):
> d1.Union(d2, new KeyValuePairComparer<string, object>())
UnionIterator { { "a", 1 }, { "b", 2 }, { "c", 3 }, { "e", 12 } }
Run Code Online (Sandbox Code Playgroud)
注意区别:
> d2.Union(d1, new KeyValuePairComparer<string, object>())
UnionIterator { { "a", 11 }, { "e", 12 }, { "c", 13 }, { "b", 2 } }
Run Code Online (Sandbox Code Playgroud)
var d3 = d1.Concat(d2.Where(kvp => ! d1.ContainsKey(kvp.Key)))
.ToDictionary(x => x.Key, x => x.Value);
Run Code Online (Sandbox Code Playgroud)
这对我有用.