今天工作遇到 英文和數字組合字符串排序的問題,故在此記錄一下
問題看如下代碼:
var list = new List<string>() { "B1", "B2", "A11", "A1", "A3", "A2" }; list = list.OrderBy(a => a).ToList(); foreach (var item in list) { Console.Write(item+";"); }
得到的結果:
A1;A11;A2;A3;B1;B2;
想要實現的效果是A11排在A3之後,但是通過默認排序 A11卻處於A1和A2之間;故滿足不了需求。
爲了滿足需求,便需要自定義排序方法
排序方法代碼如下:
public class SemiNumericComparer : IComparer<string> { public int Compare(string x, string y) { try { var xc = GetHaveCharacter(x); var yc = GetHaveCharacter(y); if (string.Compare(xc, yc, false) == 0) { var numX = 0; int.TryParse(GetNoCharacter(x), out numX); var numY = 0; int.TryParse(GetNoCharacter(y), out numY); if (numX > numY) { return 1; } else if (numX < numY) { return -1; } else { return 0; } } else { return string.Compare(xc, yc); } } catch (Exception ex) { return 0; } } private string GetHaveCharacter(string str) { //獲取字符串裏面的英文字母 Regex re = new Regex(@"[a-zA-Z]+"); Match m = re.Match(str); return m.Value; } private string GetNoCharacter(string str) { //去除字符串裏面的英文字母 return Regex.Replace(str, "[a-zA-Z]+", ""); } }
使用自定義排序:
var c = new SemiNumericComparer(); var list = new List<string>() { "B1", "B2", "A11", "A1", "A3", "A2" }; list = list.OrderBy(a => a,c).ToList(); foreach (var item in list) { Console.Write(item+";"); }
最後的結果:
A1;A2;A3;A11;B1;B2;