if you need a full comparison of both (think venn diagram results), there are four discrete outcomes for a given key assuming it is present in at least one of the dictionaries
public enum KeyCompareResult
{
ValueEqual,
NotInLeft,
NotInRight,
ValueNotEqual,
}
To get all of the keys in a dictionary, use dictionary.Keys
. To get the set of keys in either dictionary, use Enumerable.Union
, which will combine the sets and filter out duplicates.
Assuming you want some more generic method, you can then write your comparison as
public IEnumerable<KeyValuePair<TKey, KeyCompareResult>> GetDifferences<TKey, TValue>(
IDictionary<TKey, TValue> leftDict,
IDictionary<TKey, TValue> rightDict,
IEqualityComparer<TValue> comparer = null)
{
var keys = leftDict.Keys.Union(rightDict.Keys);
comparer ??= EqualityComparer<TValue>.Default;
return keys.Select(key =>
{
if (!leftDict.TryGetValue(key, out var left))
{
return KeyValuePair.Create<TKey, KeyCompareResult>(key, KeyCompareResult.NotInLeft);
}
else if (!rightDict.TryGetValue(key, out var right))
{
return KeyValuePair.Create<TKey, KeyCompareResult>(key, KeyCompareResult.NotInRight);
}
else if (!comparer.Equals(left, right))
{
return KeyValuePair.Create<TKey, KeyCompareResult>(key, KeyCompareResult.ValueNotEqual);
}
else
{
return KeyValuePair.Create<TKey, KeyCompareResult>(key, KeyCompareResult.ValueEqual);
}
});
}
The left/right distinction isn't obvious unless you are looking at the method call, so, you probably want to select the method results into messages or some other more meaningful data structure
var left = new Dictionary<int, string> { { 1, "one" }, { 2, "two" }, { 4, "four" } };
var right = new Dictionary<int, string> { { 1, "one" }, { 2, "A different value" }, { 3, "three" } };
GetDifferences(left, right, StringComparer.InvariantCulture)
.Display(); // or however you want to process the data
/*
Key Value
--- -------------
1 ValueEqual
2 ValueNotEqual
4 NotInRight
3 NotInLeft
*/