I have two Generic Dictionaries.Both have same keys.But values can be different.I want to compare 2nd dictionary with 1st dictionary .If there are differences between values
Assuming both dictionaries have the same keys, the simplest way is
var result = a.Except(b).ToDictionary(x => x.Key, x => x.Value);
EDIT
Note that a.Except(b)
gives a different result from b.Except(a)
:
a.Except(b): Price 20
b.Except(a): Price 40
converting the object to dictionary then following set concept subtract them, result items should be empty in case they are identically.
public static IDictionary<string, object> ToDictionary(this object source)
{
var fields = source.GetType().GetFields(
BindingFlags.GetField |
BindingFlags.Public |
BindingFlags.Instance).ToDictionary
(
propInfo => propInfo.Name,
propInfo => propInfo.GetValue(source) ?? string.Empty
);
var properties = source.GetType().GetProperties(
BindingFlags.GetField |
BindingFlags.GetProperty |
BindingFlags.Public |
BindingFlags.Instance).ToDictionary
(
propInfo => propInfo.Name,
propInfo => propInfo.GetValue(source, null) ?? string.Empty
);
return fields.Concat(properties).ToDictionary(key => key.Key, value => value.Value); ;
}
public static bool EqualsByValue(this object source, object destination)
{
var firstDic = source.ToFlattenDictionary();
var secondDic = destination.ToFlattenDictionary();
if (firstDic.Count != secondDic.Count)
return false;
if (firstDic.Keys.Except(secondDic.Keys).Any())
return false;
if (secondDic.Keys.Except(firstDic.Keys).Any())
return false;
return firstDic.All(pair =>
pair.Value.ToString().Equals(secondDic[pair.Key].ToString())
);
}
public static bool IsAnonymousType(this object instance)
{
if (instance == null)
return false;
return instance.GetType().Namespace == null;
}
public static IDictionary<string, object> ToFlattenDictionary(this object source, string parentPropertyKey = null, IDictionary<string, object> parentPropertyValue = null)
{
var propsDic = parentPropertyValue ?? new Dictionary<string, object>();
foreach (var item in source.ToDictionary())
{
var key = string.IsNullOrEmpty(parentPropertyKey) ? item.Key : $"{parentPropertyKey}.{item.Key}";
if (item.Value.IsAnonymousType())
return item.Value.ToFlattenDictionary(key, propsDic);
else
propsDic.Add(key, item.Value);
}
return propsDic;
}
originalObj.EqualsByValue(messageBody); // will compare values.
source of the code
to check any difference,
dic1.Count == dic2.Count && !dic1.Except(dic2).Any();
following code return all the different values
dic1.Except(dic2)
If you've already checked that the keys are the same, you can just use:
var dict3 = dict2.Where(entry => dict1[entry.Key] != entry.Value)
.ToDictionary(entry => entry.Key, entry => entry.Value);
To explain, this will:
dict2
dict1
and filter out any entries where the two values are the samedict1
value is different) by taking the key and value from each pair just as they appear in dict2
.Note that this avoids relying on the equality of KeyValuePair<TKey, TValue> - it might be okay to rely on that, but personally I find this clearer. (It will also work when you're using a custom equality comparer for the dictionary keys - although you'd need to pass that to ToDictionary
, too.)
try :
dictionary1.OrderBy(kvp => kvp.Key)
.SequenceEqual(dictionary2.OrderBy(kvp => kvp.Key))