It'sNotALie.
It'sNotALie.

Reputation: 22794

How to check if two dictionaries contain the same values?

I've got this, but it's so short I'm nearly sure I'm missing something:

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));
}

So basically, if they have an equal reference, return true. If either of them are null or their counts are different, return false. Then return if the sequences (ordered by their keys and then their values) are the same. I must be missing something, as it's far too short to be good enough.

Upvotes: 1

Views: 2197

Answers (1)

Servy
Servy

Reputation: 203829

Yes, your code will work, so long as the keys all implement IComparable and both the keys and values have an Equals method that compares what you want it to compare. If either the keys or the values don't have appropriate implementations of those methods then this won't work.

Your method also doesn't provide functionality for custom IComparer or IEqualityComparer objects to be passed in to account for the cases where the object doesn't have a desirable implementation of one of those methods. Whether this is an issue in your particular case we can't say.

Your solution also needs to sort all of the values, which is somewhat less efficient than other possible implementations of a set equals, but it's not dramatically worse, so if you don't have particularly large collections that shouldn't be a huge issue.

A method with comparable functionality to yours but improved speed would be (keeping the first two checks you have):

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

Since this method doesn't rely on sorting it also provides the benefit of not needing TKey to implement IComparable.

A key reason that both this method and your method works is due to the fact that KeyValuePair overrides it's definition of Equals and GetHashCode to to be based on it's own reference, but rather on the key and value it wraps. Two KeyValuePairs are equal if both the keys and values are equal, and the hash code incorporates the hash code of both the key and the value.

Upvotes: 4

Related Questions