.NET 5.0
做过.NET开发的都知道,Linq查询表达式中,OrderBy可以实现序列的升序排列。
new string[] { "2", "1", "0", "3", "10", "4", "12", "14", "11", "13" }.OrderBy(s => s).ToArray();
所以,我以为这句代码执行的结果是这样的:
["0", "1", "2", "3", "4", "10", "11", "12", "13", "14"]
然而,他是这样的:
那么,为什么会是这样的?
其实我心里第一反应是字符串排序是按照ASCII码排序,但是好像并没有10,11,12,13,14等对应的ASCII码,这就有点尴尬了。
经过几番百度后,或许找到了一种解释:ASCII码只针对字符,而10,11,12等有两个字符,所以编译器只会认前一个字符,所以10,11,12,13,14等字符串都被看做是'1'这个字符,如此便解释的通了。
OrderBy方法有两个重载,其中一个多了一个IComparer<T>类型的参数,通过实现IComparer<T>接口,我们可以自定义排序规则:
public class StringNumberComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (x == y)
return 0;
bool xIsNum = int.TryParse(x, out int xNum);
bool yIsNum = int.TryParse(y, out int yNum);
if (xIsNum && yIsNum)
return xNum > yNum ? 1 : -1;
else
return string.CompareOrdinal(x, y);
}
}
Icomparer<T>接口需要实现Compare方法,比较两个参数,根据泛型类型T来决定两个参数的类型。方法返回0表示x和y相等,返回负数表示x小于y,返回正数表示x大于y。上述代表表示当x和y都可以转为int类型时,按int类型时的大小来决定谁大谁小,否则就按默认的比较方法来决定谁大谁小。
调用OrderBy时传入一个StringNumberComparer对象:
#region 自定义数字字符串排序
{
var strArr = new string[] { "2", "1", "0", "3", "10", "4", "12", "14", "11", "13" };
var orderStrArr = strArr.OrderBy(s => s, new StringNumberComparer()).ToArray();
Console.WriteLine("-----------自定义数字字符串排序-----------");
Console.WriteLine($"升序排序:{string.Join(",", orderStrArr)}");
}
#endregion
查看运行结果:
成功实现了数字字符串升序排序。
通过实现IComparer<T>接口的Compare方法,可以任意自定义规则进行排序的比较,是一个高度开放的API。
跟不落阁,学DOTNET!关注公众号,获取更多干货。
版权声明:本文由不落阁原创出品,转载请注明出处!
广告位
暂无评论,大侠不妨来一发?
跟不落阁,学DOTNET!
广告位
暂时没有任何数据