【问题标题】:How to use a custom Comparer to sort an Array in a different lexical order?如何使用自定义比较器以不同的词法顺序对数组进行排序?
【发布时间】:2016-02-14 17:24:01
【问题描述】:

所以,我是 C# 的新手,我正在尝试使用自定义比较器订购一个数组。

我创建了一个类:

class MySorter : IComparer
{
    public int Compare(object x, object y)
    {
        var chars = "jngmclqskrzfvbwpxdht";
        if (chars.IndexOf((char)x) < chars.IndexOf((char)y))
            return -1;
        return chars.IndexOf((char)x) > chars.IndexOf((char)y) ? 1 : 0;
    }
}

我有一个充满单词的数组。 使用此比较进行排序的准确程度如何?

【问题讨论】:

    标签: c# sorting compare


    【解决方案1】:

    我认为你需要的是这个。像你已经做的那样声明一个排序方法。

    public static int CompareStrings(string s1, string s2)
    {
        // TODO: your code here
    }
    

    ...并指定您需要使用的功能。

    string[] myStrings = { ... };
    Array.Sort(myStrings, CompareStrings);
    

    如果您使用泛型类,您可以按照以下方式实现这一点:

    List<string> myStrings = ...;
    myStrings.Sort(CompareStrings);
    

    【讨论】:

    • 好的,现在我可以使用我的方法了,但是我在这里遇到了 InvalidCastException:if (chars.IndexOf((char)x) &lt; chars.IndexOf((char)y)) 知道为什么吗?
    • x 是objectstring,因此您需要将其转换为字符,而不是(char)x,而是Convert.ToChar(x)
    • 我之前尝试过,但后来我得到了一个“System.FormatException”。我认为这种情况正在发生,因为我在那里有整个字符串。例如“gmxz”。在比较之前是否需要对我的字符串进行子串化并仅获取第一个字符?
    • 不一定。您也可以比较字符串,但使用Equals() 方法。好吧,如果你有一个字符串,你不能把它转换成一个字符,你需要一个字符一个字符地传递,或者传递整个字符串并比较字符串,而不是字符。
    【解决方案2】:

    要回答这个问题对于希望使用 Linq 的人,解决方案是:

    IEnumerable<string> words = new [] {"foo", "bar"};
    words = words.OrderBy(x => x, new MySorter());
    

    因此请注意,您应该为比较器使用通用接口:

    class MySorter : IComparer<string>
    {
        public int Compare(string x, string y)
        {
    
        }
    }
    

    然后您可以使用 Linq 对偶数对象进行排序:

    IEnumerable<Person>  people = new []
    {
        new Person
        {
            Name = "Matthew"
        },
        new Person
        {
            Name = "Mark"
        }
    };
    people = people.OrderBy(x => x.Name, new MySorter());
    

    关于您在 Simply Me 的回答中强调的一些问题的重要说明:

    当被比较的类型已知时,使用通用接口总是更可取,因为这会在编译时而不是运行时提醒您(当您收到 InvalidCastException 时)如果您正在对 words 数组进行排序,假设一个单词是 string,那么您正在实现的 IComparer 不适合目的,因为它正在比较两个 char 类型。

    (根据我通过查看您的代码所推断的内容,我认为您需要做的是实现 IComparer&lt;string&gt; 并在 Compare 方法中遍历两个字符串的每个 char 直到它们不同,然后使用您的 char 比较逻辑 - 但是,您还应该考虑如何处理大写和小写,当一个或两个字符不在您的列表中以及一个 string 是否与另一个 @ 的第一部分完全匹配时您会做什么987654333@,例如 matchmatches。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-11
      • 2014-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多