在c#中测试字典之间的相等性

ron*_*y l 56 c# dictionary equality

假设字典键和值的equals和hash方法正确实现,那么测试两个字典相等的最简洁有效的方法是什么?

在这种情况下,如果它们包含相同的一组键(顺序并不重要),则说两个字典是相等的.对于每个这样的键,它们都同意该值.

这里有一些我提出的方法(可能还有更多):

public bool Compare1<TKey, TValue>(
    Dictionary<TKey, TValue> dic1, 
    Dictionary<TKey,TValue> dic2)
{
    return dic1.OrderBy(x => x.Key).
        SequenceEqual(dic2.OrderBy(x => x.Key));
}

public bool Compare2<TKey, TValue>(
    Dictionary<TKey, TValue> dic1, 
    Dictionary<TKey, TValue> dic2)
{
    return (dic1.Count == dic2.Count && 
        dic1.Intersect(dic2).Count().
        Equals(dic1.Count));
}

public bool Compare3<TKey, TValue>(
    Dictionary<TKey, TValue> dic1, 
    Dictionary<TKey, TValue> dic2)
{
    return (dic1.Intersect(dic2).Count().
        Equals(dic1.Union(dic2).Count()));
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*nes 94

dic1.Count == dic2.Count && !dic1.Except(dic2).Any();
Run Code Online (Sandbox Code Playgroud)

  • @ SebastianP.R.Gingter:一个`字典<TKEY的,TValue >>`也IEnumerable的的`实例<KeyValuePair <TKEY的,TValue >>`.所以你要比较`KeyValuePair <TKey,TValue>`的实例,如果密钥和值都相等,它们是相等的. (13认同)
  • 为什么这被接受并被投票?它没有做OP所要求的,即***和每一个这样的密钥,他们同意价值.*** (6认同)
  • 我相信只有在Dictionary的键和值类型仅使用内置类型或正确设置IEqualityComparer的自定义类时,此答案才有效.虽然,我会使用`dict1.SequenceEqual(dict2)`.它在键或值是集合的地方不起作用,例如List <string>.(见我的回答.) (5认同)
  • 为什么这是正确的?它不尊重所需的值的相等性.它会检查两个词典中所有键的存在. (4认同)
  • 这个答案是正确的"**假设[所有]字典键和值的等号和哈希方法正确实现**" - 方法`except()`将对字典中的`KeyValuePair`执行设置差异,并且每个`KeyValuePair`将委托给键和值上的`Equals`和`GetHashCode`方法(因此必须正确实现这些方法的原因).如果键和值是列表或字典,则这将无法按预期工作,因为这些类型仅使用"Equals"和"GetHashCode"的引用相等性. (4认同)
  • 对不起,现在已经添加了缺失,以使其不正确.字典是相同的,如果它们的大小相同,并且没有任何元素在第一个而不在第二个中. (2认同)

Luk*_*keH 13

这实际上取决于你的平等意味着什么.

此方法将测试两个字典包含具有相同值的相同键(假设两个字典使用相同的IEqualityComparer<TKey>实现).

public bool CompareX<TKey, TValue>(
    Dictionary<TKey, TValue> dict1, Dictionary<TKey, TValue> dict2)
{
    if (dict1 == dict2) return true;
    if ((dict1 == null) || (dict2 == null)) return false;
    if (dict1.Count != dict2.Count) return false;

    var valueComparer = EqualityComparer<TValue>.Default;

    foreach (var kvp in dict1)
    {
        TValue value2;
        if (!dict2.TryGetValue(kvp.Key, out value2)) return false;
        if (!valueComparer.Equals(kvp.Value, value2)) return false;
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 你不是在倒空这本字典吗?自第二个参数为空以来,comparex将第二次调用失败.为什么修改字典 - 这是否违反了关于简单相等检查的原则? (2认同)

Lee*_*Lee 7

您可以使用 linq 进行键/值比较:

public bool Compare<TKey, TValue>(Dictionary<TKey, TValue> dict1, Dictionary<TKey, TValue dict2)
{
    IEqualityComparer<TValue> valueComparer = EqualityComparer<TValue>.Default;

    return  dict1.Count == dict2.Count &&
            dict1.Keys.All(key => dict2.ContainsKey(key) && valueComparer.Equals(dict1[key], dict2[key]));
}
Run Code Online (Sandbox Code Playgroud)