2013-06-05 277 views
1

我这有,但它是如此短暂,我几乎肯定我失去了一些东西:如何检查两个字典是否包含相同的值?

public static bool ValueEquals<TKey, TValue> 
    (this IDictionary<TKey, TValue> source, IDictionary<TKey, TValue> toCheck) 
{ 
    if (object.ReferenceEquals(source, toCheck)) 
     return true; 
    if (source == null || toCheck == null || source.Count != toCheck.Count) 
     return false; 
    return source.OrderBy(t => t.Key).SequenceEqual(toCheck.OrderBy(t => t.Key)); 
} 

所以基本上,如果他们有一个平等的引用,返回true。如果它们中的任何一个是null或者它们的计数不同,则返回false。然后返回,如果序列(按键,然后它们的值排序)是相同的。我必须缺少的东西,因为它太短,不够好。

+0

对不起!我不小心按下了输入!它尚未完成! –

+2

只是为了澄清,你想要相同的值*为相同的键*? (你的问题标题只提及值,这是不同的。) –

+0

@JonSkeet我的意思是一般意义上的值,而不是'Dictionary'的价值意义。所以如果我有两个'string'和'bool'字典,它们是'{“true”,true},{“false”,false},另一个是'{“false”,false},{ “真实的”,“真实的”,他们会是平等的。抱歉,模棱两可。 –

回答

4

是的,只要所有的密钥都实现IComparable,并且密钥和值都有一个Equals方法来比较您想要比较的内容,那么您的代码将起作用。如果键或值没有这些方法的适当实现,那么这将不起作用。

您的方法也不提供自定义的IComparerIEqualityComparer对象的功能,以解决对象没有合理实现其中一种方法的情况。无论这是你的特定情况下的问题,我们不能说。

您的解决方案也需要排序的所有值,这是有点比的设定等于其他可能的实施效率较低的,但它不是大幅差,所以如果你没有特别大的集合是不该”这是一个巨大的问题。

相媲美的功能,你的方法,但改善的速度会(让你拥有前两个检查):

return !source.Except(toCheck).Any(); 

由于这种方法不依赖于排序它也提供不需要的好处TKey执行IComparable

一个重要原因,无论这种方法,你的方法效果是由于KeyValuePair覆盖它的EqualsGetHashCode定义是基于它自己的参考,而是对密钥并将其包装价值的事实。如果密钥和值都相等,则两个KeyValuePairs是相等的,并且哈希码包含密钥和值的哈希码。

+0

感谢此:) –

+0

速度可以进一步提高,我想如果通过一个字典枚举,试图从另一个字典中读取每个值,并确保读取了一个值,并且它与源中的值匹配。不需要建立交集。 – supercat

+0

@supercat如果它们相同,它们会变得更快并且速度更慢,但是如果它们是相同的,我会将它们包括在内,这可能是值得的。 – Servy

相关问题