Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing 2 Dictionary<string, string> Instances

I want to compare the contents of two Dictionary<string, string> instances regardless of the order of the items they contain. SequenceEquals also compares the order, so I first order the dictionaries by key and then call SequenceEquals.

Is there a method that I can use instead of SequenceEquals that will only compare the contents?

If there isn't, is this the ideal way to do this?

Dictionary<string, string> source = new Dictionary<string, string>(); Dictionary<string, string> target = new Dictionary<string, string>();  source["foo"] = "bar"; source["baz"] = "zed"; source["blah"] = null;  target["baz"] = "zed"; target["blah"] = null; target["foo"] = "bar";  // sequenceEquals will be false var sequenceEqual = source.SequenceEqual(target); // contentsEqual will be true var contentsEqual = source.OrderBy(x => x.Key).SequenceEqual(target.OrderBy(x => x.Key)); 
like image 742
Jeff Ogata Avatar asked Oct 13 '10 23:10

Jeff Ogata


2 Answers

var contentsEqual = source.DictionaryEqual(target);  // ...  public static bool DictionaryEqual<TKey, TValue>(     this IDictionary<TKey, TValue> first, IDictionary<TKey, TValue> second) {     return first.DictionaryEqual(second, null); }  public static bool DictionaryEqual<TKey, TValue>(     this IDictionary<TKey, TValue> first, IDictionary<TKey, TValue> second,     IEqualityComparer<TValue> valueComparer) {     if (first == second) return true;     if ((first == null) || (second == null)) return false;     if (first.Count != second.Count) return false;      valueComparer = valueComparer ?? EqualityComparer<TValue>.Default;      foreach (var kvp in first)     {         TValue secondValue;         if (!second.TryGetValue(kvp.Key, out secondValue)) return false;         if (!valueComparer.Equals(kvp.Value, secondValue)) return false;     }     return true; } 
like image 168
LukeH Avatar answered Oct 03 '22 06:10

LukeH


I don't know if there is an existing method but you could use the following (null checking of args omitted for brevity)

public static bool DictionaryEquals<TKey,TValue>(   this Dictionary<TKey,TValue> left,   Dictionary<TKey,TValue> right ) {     var comp = EqualityComparer<TValue>.Default;   if ( left.Count != right.Count ) {      return false;   }   foreach ( var pair in left ) {     TValue value;     if ( !right.TryGetValue(pair.Key, out value)           || !comp.Equals(pair.Value, value) ) {       return false;     }   }    return true; } 

It would be best to add an overload to allow customization of the EqualityComparer<TValue>.

like image 38
JaredPar Avatar answered Oct 03 '22 04:10

JaredPar