web-dev-qa-db-de.com

Vergleich von 2 Dictionary <string, string> -Instanzen

Ich möchte den Inhalt zweier Dictionary<string, string>-Instanzen unabhängig von der Reihenfolge der darin enthaltenen Elemente vergleichen. SequenceEquals vergleicht auch die Reihenfolge. Ich ordne die Wörterbücher zuerst mit dem Schlüssel an und rufe dann SequenceEquals auf. 

Gibt es eine Methode, die ich anstelle von SequenceEquals verwenden kann, die nur den Inhalt vergleicht?

Wenn nicht, ist dies der ideale Weg, dies zu tun?

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));
36
Jeff Ogata
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;
}
53
LukeH

Ich weiß nicht, ob es eine existierende Methode gibt, aber Sie könnten die folgende verwenden

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

Am besten fügen Sie eine Überladung hinzu, um die Anpassung des EqualityComparer<TValue> zu ermöglichen. 

6
JaredPar

Wenn Sie ein SortedDictionary verwenden, müssen Sie die Sortierung nicht selbst vornehmen.

void Main()
{
    var d1 = new Dictionary<string, string>
    {
        ["a"] = "Hi there!",
        ["b"] = "asd",
        ["c"] = "def"
    };
    var d2 = new Dictionary<string, string>
    {
        ["b"] = "asd",
        ["a"] = "Hi there!",
        ["c"] = "def"
    };

    var sortedDictionary1 = new SortedDictionary<string, string>(d1);
    var sortedDictionary2 = new SortedDictionary<string, string>(d2);

    if (sortedDictionary1.SequenceEqual(sortedDictionary2))
    {
        Console.WriteLine("Match!");
    }
    else
    {
        Console.WriteLine("Not match!");
    }
}
0
RB.