代码之家  ›  专栏  ›  技术社区  ›  Magnus Johansson

如何为SortedDictionary使用自定义IComparer?

  •  9
  • Magnus Johansson  · 技术社区  · 14 年前

    我的SortedDictionary<>无法使用自定义iComparer。目标是将电子邮件地址以特定格式(firstnam.last name@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);
      }
    }
    

    我得到这个论点例外: An entry with the same key already exists. 添加第二项时。

    我以前没有为SortedDictionary使用过自定义的IComparer,我看不到我的错误,我做错了什么?

    2 回复  |  直到 14 年前
        1
  •  5
  •   digEmAll    14 年前

    如果两个姓相等,则比较整个电子邮件,例如:

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

    实际上,SortedDictionary Comparison还用于区分键*,因此必须指定一个完整的比较(不仅仅是排序策略)。

    编辑: *我的意思是在SortedDictionary中,如果比较器给出0,则2个键相等。

        2
  •  1
  •   Jon Skeet    14 年前

    好吧,我还没有把你的比较器拆开——但看起来它只是按姓氏比较,而你想加两次相同的姓氏(约翰森)。那 应该 给你一个 ArgumentException .

    你做了什么? 希望 会发生什么事 希望 你的比较器呢?

    也许你想按姓氏排序 然后是名字 ?这样,您就可以拥有两个姓氏相同但名字不同的电子邮件地址,并将它们放在字典中,按名字排序。