如何在C#中对含数字与带字符数字的List进行Sort排序?
C# 实现混合类型列表的自然排序
要实现你需要的排序效果,本质是自然排序(人性化排序):先按字符串中的数字部分数值大小排序,数字相同时再按后续字母的字典序排序。由于列表中混合了字符串和整数类型,第一步需要统一将所有元素转为字符串,再通过自定义比较器完成排序。
自定义自然排序比较器
这个比较器会自动提取字符串中的数字部分和非数字部分,分别进行比较:
public class NaturalStringComparer : IComparer<string> { public int Compare(string x, string y) { if (x == null && y == null) return 0; if (x == null) return -1; if (y == null) return 1; int xIndex = 0, yIndex = 0; while (xIndex < x.Length && yIndex < y.Length) { if (char.IsDigit(x[xIndex]) && char.IsDigit(y[yIndex])) { // 提取连续的数字段 string xNum = ExtractNumber(x, ref xIndex); string yNum = ExtractNumber(y, ref yIndex); // 优先按数字数值比较 if (int.TryParse(xNum, out int xInt) && int.TryParse(yNum, out int yInt)) { int numCompare = xInt.CompareTo(yInt); if (numCompare != 0) return numCompare; } else { // 数字解析失败时按字符串原序比较 int strCompare = xNum.CompareTo(yNum); if (strCompare != 0) return strCompare; } } else { // 非数字部分直接按字符字典序比较 int charCompare = x[xIndex].CompareTo(y[yIndex]); if (charCompare != 0) return charCompare; xIndex++; yIndex++; } } // 处理长度差异:短字符串排在前面 return x.Length.CompareTo(y.Length); } // 提取从当前索引开始的连续数字字符串 private string ExtractNumber(string s, ref int index) { StringBuilder sb = new StringBuilder(); while (index < s.Length && char.IsDigit(s[index])) { sb.Append(s[index]); index++; } return sb.ToString(); } }
使用示例
将混合类型列表转为字符串列表后,用自定义比较器排序:
// 初始化混合类型列表 List<object> mixedList = new List<object> { "301", "301b", "301a", "300", 302 }; // 方式1:用LINQ的OrderBy排序 List<string> sortedList = mixedList .Select(item => item.ToString()) .OrderBy(str => str, new NaturalStringComparer()) .ToList(); // 方式2:用List的Sort方法排序 List<string> stringList = mixedList.Select(item => item.ToString()).ToList(); stringList.Sort(new NaturalStringComparer()); // 输出验证结果 foreach (var item in sortedList) { Console.WriteLine(item); }
执行后会得到你期望的排序结果:300、301、301a、301b、302。
内容的提问来源于stack exchange,提问作者bijoy patwal
相关产品推荐
相关产品推荐

