平等について2つの辞書を比較する最良の方法
-
29-10-2019 - |
質問
これは、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の実装についてはあまりわかりません。
ありがとう!
解決
これが私がすることです:
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) 操作):最初の辞書のエントリを列挙するだけでいい(の上))そして、2番目の辞書のキーで値を取得してみてください(O(1))、したがって、全体的な複雑さです の上).
また、あなたに注意してください GetHashCode
方法が正しくありません:ほとんどの場合、同じコンテンツがある場合でも、異なる辞書インスタンスの異なる値を返します。そして、ハッシュコードが異なる場合、 Equals
決して呼ばれることはありません...あなたはそれを正しく実装するためのいくつかのオプションがあり、それらのどれも理想的ではありません:
- 辞書のコンテンツからハッシュコードを構築します:最良のオプションですが、それは遅いです、そして
GetHashCode
速くする必要があります - そのように、常に同じ値を返してください
Equals
常に呼ばれます: とても ハッシュテーブル/辞書/ハッシュセットでこの比較を使用したい場合は悪いです。すべてのインスタンスが同じバケツに収まるため、 の上) の代わりにアクセス O(1) - 戻ります
Count
辞書の(Digemallによって示唆されているように):それは大きな分布を与えませんが、常に同じ値を返すよりも優れており、の制約を満たしますGetHashCode
(つまり、等しいと見なされるオブジェクトには同じハッシュコードが必要です。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]));
}
おそらく最速ではなく、働いているのは私には良いようです。
変更するだけです GetHashCode
間違っている実装。
たとえば、返すことができます obj.Columns.Count.GetHashCode()
所属していません StackOverflow