如何实现C#中含数字的字符串对象列表的自然排序?
解决字符串自然排序问题
当前代码使用默认字符串字典序排序,导致包含数字的标题排序结果不符合预期("100"排在"11"前面),以下是两种可行的解决方案:
方案一:提取数字部分排序
适合标题格式固定(数字位于末尾)的场景,通过提取标题中的数字转换为整数,按整数数值排序:
// 提取标题中的数字并转换为整数 private static int ExtractTitleNumber(string title) { var digitChars = new string(title.Where(char.IsDigit).ToArray()); return int.TryParse(digitChars, out int number) ? number : 0; } // 修改排序逻辑 var ordered = list.OrderBy(s => ExtractTitleNumber(s.Title)).Select(x => x.Title);
执行后将得到预期结果:
SP's Aviation 10, SP's Aviation 11, SP's Aviation 100, SP's Aviation 101
方案二:使用.NET内置数字排序比较器
通用性更强,支持数字出现在字符串任意位置的场景,利用CompareInfo的数字排序规则实现自然排序:
var currentCulture = CultureInfo.CurrentCulture; var ordered = list.OrderBy(s => s.Title, Comparer<string>.Create((a, b) => currentCulture.CompareInfo.Compare(a, b, CompareOptions.NumericOrdering))).Select(x => x.Title);
问题根源
默认的OrderBy(s => s.Title)采用字典序排序,逐个字符比较ASCII值:
- 比较"SP's Aviation 100"和"SP's Aviation 11"时,第16个字符'0'的ASCII值小于'1',因此"100"会排在"11"前面,不符合数字大小的排序逻辑;
- 自然排序会将连续数字视为一个整体,按数字实际数值比较,因此能得到10 < 11 < 100 < 101的正确顺序。
内容的提问来源于stack exchange,提问作者Paul Green
相关产品推荐
相关产品推荐

