11 Stimmen

Wie verwendet man einen eigenen IComparer für SortedDictionary?

Ich habe Schwierigkeiten, meinen benutzerdefinierten IComparer für mein SortedDictionary<> zu verwenden. Das Ziel ist es, E-Mail-Adressen in einem bestimmten Format (firstnam.lastname@domain.com) als Schlüssel zu verwenden und nach Nachnamen zu sortieren. Wenn ich etwas wie dies tun:

public class Program
{
  public static void Main(string[] args)
  {
    SortedDictionary<string, string> list = new SortedDictionary<string, string>(new SortEmailComparer());
    list.Add("a.johansson@domain.com", "value1");
    list.Add("b.johansson@domain.com", "value2");
    foreach (KeyValuePair<string, string> kvp in list)
    {
      Console.WriteLine(kvp.Key);
    }
    Console.ReadLine();
  }
}

public class SortEmailComparer : IComparer<string>
{
  public int Compare(string x, string y)
  {
    Regex regex = new Regex("\\b\\w*@\\b",
                        RegexOptions.IgnoreCase
                        | RegexOptions.CultureInvariant
                        | RegexOptions.IgnorePatternWhitespace
                        | RegexOptions.Compiled
                        );

    string xLastname = regex.Match(x).ToString().Trim('@');
    string yLastname = regex.Match(y).ToString().Trim('@');
    return xLastname.CompareTo(yLastname);
  }
}

Ich erhalte diese ArgumentException: An entry with the same key already exists. beim Hinzufügen des zweiten Elements.

Ich habe nicht mit einem benutzerdefinierten IComparer für ein SortedDictionary vor gearbeitet, und ich sehe nicht meinen Fehler, was mache ich falsch?

6voto

digEmAll Punkte 54672

Wenn die 2 Nachnamen gleich sind, dann vergleichen Sie z.B. die gesamte E-Mail wie:

int comp = xLastname.CompareTo(yLastname);
if (comp == 0)
   return x.CompareTo(y);
return comp;

Der Sorteddictionary-Vergleich wird auch verwendet, um zwischen den Schlüsseln* zu unterscheiden, daher müssen Sie einen vollständigen Vergleich angeben (nicht nur Ihre Sortierstrategie)

EDIT: * Ich meine in sortedDictionary sind 2 Schlüssel gleich, wenn Comparer 0 ergibt

1voto

Jon Skeet Punkte 1325502

Nun, ich habe Ihren Komparator nicht auseinandergenommen - aber es sieht so aus, als ob er nur nach Nachnamen vergleicht, und Sie versuchen, denselben Nachnamen (johansson) zweimal hinzuzufügen. Das sollte geben Ihnen eine ArgumentException .

Was haben Sie wollen passieren soll - und was wollen Sie wollen was Ihr Vergleicher tun soll?

Vielleicht möchten Sie nach Nachnamen sortieren und dann den Vornamen ? Auf diese Weise können Sie zwei E-Mail-Adressen mit demselben Nachnamen, aber unterschiedlichen Vornamen haben und sie trotzdem zusammen im Wörterbuch finden, geordnet nach Vornamen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X