2010-04-27 4 views
7

У меня возникли трудности с использованием моего специального IComparer для моего SortedDictionary <>. Цель состоит в том, чтобы поместить адреса электронной почты в определенном формате ([email protected]) в качестве ключа и отсортировать по фамилии. Когда я сделать что-то вроде этого:Как использовать пользовательский IComparer для SortedDictionary?

public class Program 
{ 
    public static void Main(string[] args) 
    { 
    SortedDictionary<string, string> list = new SortedDictionary<string, string>(new SortEmailComparer()); 
    list.Add("[email protected]", "value1"); 
    list.Add("[email protected]", "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, и я не вижу свою ошибку, что я делаю неправильно?

ответ

4

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

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

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

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

+0

Спасибо. Это было простое элегантное решение. –

1

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

Что вы хотите случиться - и что вы хотите ваш Comparer делать?

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

+0

Действительно, ваши предположения верны. @digEmAll предоставил решение, которое я хотел, и @Foxfire объяснил, почему. –

Смежные вопросы