Как использовать пользовательский IComparer для SortedDictionary? - PullRequest
9 голосов
/ 27 апреля 2010

У меня проблемы с использованием моего пользовательского IComparer для моего SortedDictionary <>. Цель состоит в том, чтобы в качестве ключа указать адреса электронной почты определенного формата (firstnam.lastname@domain.com) и отсортировать их по фамилии. Когда я делаю что-то вроде этого:

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

Я получаю ArgumentException: An entry with the same key already exists. при добавлении второго элемента.

Я раньше не работал с пользовательским IComparer для SortedDictionary, и я не вижу свою ошибку, что я делаю неправильно?

Ответы [ 2 ]

5 голосов
/ 27 апреля 2010

Если 2 lastNames равны, сравните, например, всю электронную почту как:

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

На самом деле сортировочное сравнение также используется для различения ключей *, поэтому вы должны указать полное сравнение (не только стратегию сортировки)

EDIT: * Я имею в виду в sortedDictionary 2 ключа равны, если Comparer дает 0

1 голос
/ 27 апреля 2010

Ну, я не разобрал ваш компаратор, но похоже, что он просто сравнивает по фамилии, и вы пытаетесь добавить одну и ту же фамилию (johansson) дважды. Это должно дать вам ArgumentException.

Что вы хотели, чтобы произошло , и что вы хотите , чтобы ваш компаратор делал?

Возможно, вы хотите отсортировать по фамилии , а затем по имени ? Таким образом, у вас может быть два адреса электронной почты с одинаковыми фамилиями, но разными именами, и они будут по-прежнему находиться в словаре вместе, упорядоченные по имени.

...