5

これは、2 つの辞書が等しいかどうかを比較する比較子を作成する最良の方法ですか? これは正確である必要があります。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 の実装についてもよくわかりません。

ありがとう!

4

3 に答える 3

8

これが私がすることです:

    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)操作です)。最初の辞書 ( O(n) )でエントリを列挙し、キーで値を取得しようとするだけです。 2 番目の辞書 ( O(1) ) であるため、全体的な複雑さはO(n)です。

また、メソッドが正しくないことに注意してくださいGetHashCode。ほとんどの場合、コンテンツが同じであっても、異なる辞書インスタンスに対して異なる値を返します。そして、ハッシュコードが異なる場合、Equals呼び出されることはありません...正しく実装するためのいくつかのオプションがありますが、どれも理想的ではありません:

  • 辞書の内容からハッシュコードを構築する: 最良のオプションですが、遅いGetHashCodeので高速である必要があります
  • 常に同じ値を返します。その方法Equalsは常に呼び出されます。ハッシュテーブル/辞書/ハッシュセットでこの比較子を使用する場合は非常に悪いです。すべてのインスタンスが同じバケットに分類され、O ではなくO (n)アクセスが発生するためです。 (1)
  • ディクショナリの を返しますCount(digEmAll で提案されているように): 優れた分布は得られませんが、常に同じ値を返すよりも優れており、次の制約を満たしますGetHashCode(つまり、等しいと見なされるオブジェクトは同じハッシュコードを持つ必要があります; 2 つの「等しい」辞書には同じ数の項目があるため、機能します)
于 2011-03-23T21:25:18.427 に答える
2

このようなものが頭に浮かびますが、もっと効率的なものがあるかもしれません:

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]));
}
于 2011-03-23T21:23:32.610 に答える
1

おそらく最速ではありませんが、機能しています。

GetHashCode間違っている実装を変更するだけです。

たとえば、返すことができますobj.Columns.Count.GetHashCode()

于 2011-03-23T21:25:16.617 に答える