默认排序问题
windows排序
Windows的资源管理中,提供了文件名的智能排序功能,可以识别出文件名中数字(数字位数不相同),然后比较数字大小进行排序,如下图:
代码默认排序
但在C#中的列表排序中则是按照从左到右一个一个字符进行比较进行排序,如下图:
List<string> list=new List<string>(); list.Add("文件(11)"); list.Add("文件(22)"); list.Add("文件(1)"); list.Add("文件(2)"); list.Add("文件(3)"); list.Add("文件(4)"); list.Sort(); list.ForEach(l=>Console.WriteLine(l));
运行效果
排序改进
文件名比较方法
public static int FileNameCompare(string s1, string s2){MatchCollection matchList1 = Regex.Matches(s1, @"\d+");//找出字符串s1中的数字MatchCollection matchList2 = Regex.Matches(s2, @"\d+");//找出字符串s2中的数字int minCount = matchList1.Count >= matchList2.Count ? matchList2.Count : matchList1.Count;for (int i = 0; i < minCount; i++){//循环数字一一比较if (matchList1[i].Index != matchList2[i].Index)break;//数字位置不同,直接使用字符串比较if (s1.Substring(0, matchList1[i].Index) != s2.Substring(0, matchList2[i].Index))break;//数字之前字符不同,直接使用字符串比较if (matchList1[i].Value == matchList2[i].Value)continue;//数字相同时,比较下一组数字int s = matchList1[i].Value.Length - matchList2[i].Value.Length;if (s == 0)break;//数字位数相同,直接使用字符串比较string temp = "";if (s > 0) //这里不直接比较数字,是为了对数字之后的字符串再进行比较 {//当s1的数字长度大于s2时,对s2的前面进行补0操作,然后在比较s1与s2字符串temp = s2;for (int n = 0; n < s; n++){temp = s2.Insert(matchList2[i].Index, "0");}int r = s1.CompareTo(temp);return r == 0 ? -1 : r;}if (s < 0){//当s1的数字长度小于s2时,对s1的前面进行补0操作,然后在比较s1与s2字符串temp = s1;for (int n = 0; n < Math.Abs(s); n++){temp = s1.Insert(matchList1[i].Index, "0");}int r = temp.CompareTo(s2);return r == 0 ? 1 : r;}}return s1.CompareTo(s2);}
方法使用
List<string> list = new List<string>();list.Add("文件(11)");list.Add("文件(22)");list.Add("文(11)件(1)");list.Add("文(2)件(2)");list.Add("文件(3)");list.Add("文件(4)");list.Sort((m1, m2) => Common.THMethod.FileNameCompare(m1, m2));list.ForEach(l => Console.WriteLine(l));
效果