LINQ 和区分大小写

发布于 2024-10-22 07:55:03 字数 758 浏览 1 评论 0原文

我有这个 LINQ 查询:

TempRecordList = new ArrayList(TempRecordList.Cast<string>().OrderBy(s => s.Substring(9, 30)).ToArray());

它工作得很好,并且以准确的方式执行排序,但与我想要的有点不同。在查询结果中,我看到如下内容:

Palm-Bouter,Peter
Palmer-Johnson, Sean

而我真正需要的是按如下方式排序姓名:

Palmer-Johnson, Sean
Palm-Bouter,Peter

基本上,我希望将“-”字符视为低于该字符,以便包含它的名称稍后显示在升序搜索中。

这是另一个例子。我得到:

迪亚斯、雷金纳德
安东·迪布莱克利

而不是:

安东·迪布莱克利
Dias, Reginald

正如您所看到的,由于大写字母“B”的处理方式,顺序再次发生了变化。

所以我的问题是,我需要在 LINQ 查询中进行哪些更改才能使其按照我指定的顺序返回结果。任何反馈将不胜感激。

顺便说一句,我尝试使用 s.Substring(9, 30).ToLower() 但这没有帮助。

谢谢你!

I have this LINQ Query:

TempRecordList = new ArrayList(TempRecordList.Cast<string>().OrderBy(s => s.Substring(9, 30)).ToArray());

It works great and performs sorting in a way that's accurate but a little different from what I want. Among the the result of the query I see something like this:

Palm-Bouter, Peter
Palmer-Johnson, Sean

Whereas what I really need is to have names sorted like this:

Palmer-Johnson, Sean
Palm-Bouter, Peter

Basically I want the '-' character to be treated as being lower than the character so that names that contain it show up later in an ascending search.

Here is another example. I get:

Dias, Reginald
DiBlackley, Anton

Instead of:

DiBlackley, Anton
Dias, Reginald

As you can see, again, the order is switched due to how the uppercase letter 'B' is treated.

So my question is, what do I need to change in my LINQ query to make it return results in the order I specified. Any feedback would be greatly appreaciated.

By the way, I tried using s.Substring(9, 30).ToLower() but that didn't help.

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

娇俏 2024-10-29 07:55:03

要自定义排序顺序,您需要创建一个实现 IComparer 接口的比较器类。 OrderBy() 方法将比较器作为第二个参数。

internal sealed class NameComparer : IComparer<string> {
    private static readonly NameComparer DefaultInstance = new NameComparer();

    static NameComparer() { }
    private NameComparer() { }

    public static NameComparer Default {
        get { return DefaultInstance; }
    }

    public int Compare(string x, string y) {
        int length = Math.Min(x.Length, y.Length);
        for (int i = 0; i < length; ++i) {
            if (x[i] == y[i]) continue;
            if (x[i] == '-') return 1;
            if (y[i] == '-') return -1;
            return x[i].CompareTo(y[i]);
        }

        return x.Length - y.Length;
    }
}

这至少适用于以下测试用例:

var names = new[] {
    "Palmer-Johnson, Sean",
    "Palm-Bouter, Peter",
    "Dias, Reginald",
    "DiBlackley, Anton",
};

var sorted = names.OrderBy(name => name, NameComparer.Default).ToList();

// sorted:
// [0]: "DiBlackley, Anton"
// [1]: "Dias, Reginald"
// [2]: "Palmer-Johnson, Sean"
// [3]: "Palm-Bouter, Peter"

To customize the sorting order you will need to create a comparer class that implements IComparer<string> interface. The OrderBy() method takes comparer as second parameter.

internal sealed class NameComparer : IComparer<string> {
    private static readonly NameComparer DefaultInstance = new NameComparer();

    static NameComparer() { }
    private NameComparer() { }

    public static NameComparer Default {
        get { return DefaultInstance; }
    }

    public int Compare(string x, string y) {
        int length = Math.Min(x.Length, y.Length);
        for (int i = 0; i < length; ++i) {
            if (x[i] == y[i]) continue;
            if (x[i] == '-') return 1;
            if (y[i] == '-') return -1;
            return x[i].CompareTo(y[i]);
        }

        return x.Length - y.Length;
    }
}

This works at least with the following test cases:

var names = new[] {
    "Palmer-Johnson, Sean",
    "Palm-Bouter, Peter",
    "Dias, Reginald",
    "DiBlackley, Anton",
};

var sorted = names.OrderBy(name => name, NameComparer.Default).ToList();

// sorted:
// [0]: "DiBlackley, Anton"
// [1]: "Dias, Reginald"
// [2]: "Palmer-Johnson, Sean"
// [3]: "Palm-Bouter, Peter"
无畏 2024-10-29 07:55:03

正如已经提到的,OrderBy() 方法采用比较器作为第二个参数。

对于字符串,您不必实现IComparer。您可能可以使用System.StringComparer.CurrentCulture(或System.StringComparer中的其他选项之一)。

然而,在您的具体情况下,没有内置比较器可以处理字母排序顺序之后的-

As already mentioned, the OrderBy() method takes a comparer as a second parameter.

For strings, you don't necessarily have to implement an IComparer<string>. You might be fine with System.StringComparer.CurrentCulture (or one of the others in System.StringComparer).

In your exact case, however, there is no built-in comparer which will handle also the - after letter sort order.

朕就是辣么酷 2024-10-29 07:55:03

OrderBy() 按升序返回结果。

eh 之前,因此是第一个结果(记住您正在比较以第 9 个位置的字符开头的子字符串......而不是字符串的开头) 且 i 位于 y 之前,因此是第二个。区分大小写与此无关。

如果您希望结果按降序排列,则应使用OrderByDescending():

TempRecordList.Cast<string>
              .OrderByDescending(s => s.Substring(9, 30)).ToArray());

OrderBy() returns results in ascending order.

e comes before h, thus the first result (remember you're comparing on a substring that starts with the character in the 9th position...not the beginning of the string) and i comes before y, thus the second. Case sensitivity has nothing to do with it.

If you want results in descending order, you should use OrderByDescending():

TempRecordList.Cast<string>
              .OrderByDescending(s => s.Substring(9, 30)).ToArray());
转身泪倾城 2024-10-29 07:55:03

您可能只想实现一个自定义 IComparer 对象,该对象将为特殊、大写和小写字符赋予自定义优先级。

http://msdn.microsoft.com/en-us/library /system.collections.icomparer.aspx

You might want to just implement a custom IComparer object that will give a custom priority to special, upper-case and lower-case characters.

http://msdn.microsoft.com/en-us/library/system.collections.icomparer.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文