比较两个 Dictionary的最佳方法为了平等

发布于 2024-10-26 02:25:52 字数 642 浏览 7 评论 0原文

这是创建两个字典相等的比较器的最佳方法吗?这需要准确。请注意,Entity.Columns 是 KeyValuePair(string, object) 的字典:

public class EntityColumnCompare : IEqualityComparer<Entity>
{
    public bool Equals(Entity a, Entity b)
    {
        var aCol = a.Columns.OrderBy(KeyValuePair => KeyValuePair.Key);
        var bCol = b.Columns.OrderBy(KeyValuePAir => KeyValuePAir.Key); 

        if (aCol.SequenceEqual(bCol))
            return true;
        else
            return false;           
    }

    public int GetHashCode(Entity obj)
    {
        return obj.Columns.GetHashCode(); 
    }
}

也不太确定 GetHashCode 实现。

谢谢!

Is this the best way to create a comparer for the equality of two dictionaries? This needs to be exact. Note that Entity.Columns is a dictionary of KeyValuePair(string, object) :

public class EntityColumnCompare : IEqualityComparer<Entity>
{
    public bool Equals(Entity a, Entity b)
    {
        var aCol = a.Columns.OrderBy(KeyValuePair => KeyValuePair.Key);
        var bCol = b.Columns.OrderBy(KeyValuePAir => KeyValuePAir.Key); 

        if (aCol.SequenceEqual(bCol))
            return true;
        else
            return false;           
    }

    public int GetHashCode(Entity obj)
    {
        return obj.Columns.GetHashCode(); 
    }
}

Also not too sure about the GetHashCode implementation.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

南笙 2024-11-02 02:25:52

这就是我要做的:

    public bool Equals(Entity a, Entity b)
    {
        if (a.Columns.Count != b.Columns.Count)
            return false; // Different number of items

        foreach(var kvp in a.Columns)
        {
            object bValue;
            if (!b.Columns.TryGetValue(kvp.Key, out bValue))
                return false; // key missing in b
            if (!Equals(kvp.Value, bValue))
                return false; // value is different
        }
        return true;
    }

这样你就不需要对条目进行排序(这是一个O(n log n)操作):你只需要枚举第一个字典中的条目(< em>O(n)) 并尝试通过第二个字典中的键检索值 (O(1)),因此整体复杂度为 O(n)嗯>。

另请注意,您的 GetHashCode 方法不正确:在大多数情况下,即使它们具有相同的内容,它也会为不同的字典实例返回不同的值。如果哈希码不同,Equals 将永远不会被调用...您有多种选择来正确实现它,但没有一个是理想的:

  • 从字典的内容构建哈希码:将是最好的选项,但它很慢,并且 GetHashCode 需要很快,
  • 始终返回相同的值,这样 Equals 将始终被调用:非常如果您想在哈希表/字典/哈希集中使用此比较器,因为所有实例都将落入同一个存储桶中,从而导致 O(n) 访问而不是 O(1)
  • 返回字典的 Count (按照 digEmAll 的建议):它不会给出很好的分布,但仍然比总是返回相同的值要好,并且它满足 GetHashCode 的约束 (即被认为相等的对象应该具有相同的哈希码;两个“相等”的字典具有相同数量的项目,因此它可以工作)

Here's what I would do:

    public bool Equals(Entity a, Entity b)
    {
        if (a.Columns.Count != b.Columns.Count)
            return false; // Different number of items

        foreach(var kvp in a.Columns)
        {
            object bValue;
            if (!b.Columns.TryGetValue(kvp.Key, out bValue))
                return false; // key missing in b
            if (!Equals(kvp.Value, bValue))
                return false; // value is different
        }
        return true;
    }

That way you don't need to order the entries (which is a O(n log n) operation) : you only need to enumerate the entries in the first dictionary (O(n)) and try to retrieve values by key in the second dictionary (O(1)), so the overall complexity is O(n).

Also, note that your GetHashCode method is incorrect: in most cases it will return different values for different dictionary instances, even if they have the same content. And if the hashcode is different, Equals will never be called... You have several options to implement it correctly, none of them ideal:

  • build the hashcode from the content of the dictionary: would be the best option, but it's slow, and GetHashCode needs to be fast
  • always return the same value, that way Equals will always be called: very bad if you want to use this comparer in a hashtable/dictionary/hashset, because all instances will fall in the same bucket, resulting in O(n) access instead of O(1)
  • return the Count of the dictionary (as suggested by digEmAll): it won't give a great distribution, but still better than always returning the same value, and it satisfies the constraint for GetHashCode (i.e. objects that are considered equal should have the same hashcode; two "equal" dictionaries have the same number of items, so it works)
帅冕 2024-11-02 02:25:52

我想到了类似的东西,但可能还有更有效的东西:

public static bool Equals<TKey, TValue>(IDictionary<TKey, TValue> x, 
    IDictionary<TKey, TValue> y)
{
    return x.Keys.Intersect(y.Keys).Count == x.Keys.Count &&
        x.Keys.All(key => Object.Equals(x[key], y[key]));
}

Something like this comes to mind, but there might be something more efficient:

public static bool Equals<TKey, TValue>(IDictionary<TKey, TValue> x, 
    IDictionary<TKey, TValue> y)
{
    return x.Keys.Intersect(y.Keys).Count == x.Keys.Count &&
        x.Keys.All(key => Object.Equals(x[key], y[key]));
}
瞳孔里扚悲伤 2024-11-02 02:25:52

对我来说这似乎很好,也许不是最快的,但很有效。

您只需更改错误的 GetHashCode 实现即可。

例如,您可以返回 obj.Columns.Count.GetHashCode()

It seems good to me, perhaps not the fastest but working.

You just need to change the GetHashCode implementation that is wrong.

For example you could return obj.Columns.Count.GetHashCode()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文