LINQ和CASE灵敏度

时间:2011-03-16 16:50:54

标签: linq sorting linq-to-objects case-sensitive

我有这个LINQ查询:

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

它运行良好,并以一种准确但与我想要的有点不同的方式进行排序。在查询的结果中,我看到这样的事情:

Palm-Bouter,彼得
帕尔默 - 约翰逊,肖恩

而我真正需要的是将名称排序如下:

Palmer-Johnson,Sean
Palm-Bouter,Peter

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

这是另一个例子。我明白了:

Dias,Reginald
迪布莱克利,安东

而不是:

DiBlackley,Anton
迪亚斯,雷金纳德

正如您所看到的,由于大写字母“B”的处理方式,订单会再次切换。

所以我的问题是,我需要在LINQ查询中更改什么才能使其按照我指定的顺序返回结果。任何反馈都会有很大的反应。

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

谢谢!

4 个答案:

答案 0 :(得分:6)

要自定义排序顺序,您需要创建一个实现IComparer<string>接口的比较器类。 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"

答案 1 :(得分:2)

如前所述,OrderBy()方法将比较器作为第二个参数。

对于字符串,您不必实施IComparer<string>System.StringComparer.CurrentCulture(或System.StringComparer中的其他人之一)可能没问题。

但是,在您的确切情况下,没有内置的比较器也可以处理字母排序顺序后的-

答案 2 :(得分:0)

OrderBy()按升序返回结果。

e出现在h之前,因此是第一个结果(记住你要比较一个从第9个位置的字符开始的子字符串...而不是字符串的开头)和{ {1}}来自i,因此是第二个。区分大小写与它无关。

如果您希望降序排列结果,则应使用y

OrderByDescending()

答案 3 :(得分:0)

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

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