Default sorting problem
windows sorting
In the resource management of Windows, the intelligent sorting function of file names is provided, which can identify the numbers in file names (the number of digits is different), and then compare the number sizes for sorting, as shown in the following figure:
Code default sort
But in the list sorting in C ා, it is sorted by comparing one character from left to right, as shown in the following figure:
List<string> list=new List<string>(); list.Add("file(11)"); list.Add("file(22)"); list.Add("file(1)"); list.Add("file(2)"); list.Add("file(3)"); list.Add("file(4)"); list.Sort(); list.ForEach(l=>Console.WriteLine(l));
Operation effect
Sorting improvement
File name comparison method
public static int FileNameCompare(string s1, string s2) { MatchCollection matchList1 = Regex.Matches(s1, @"\d+");//Find string s1 Number in MatchCollection matchList2 = Regex.Matches(s2, @"\d+");//Find string s2 Number in int minCount = matchList1.Count >= matchList2.Count ? matchList2.Count : matchList1.Count; for (int i = 0; i < minCount; i++) {//Cycle numbers one by one comparison if (matchList1[i].Index != matchList2[i].Index) break;//Different number positions, direct use of string comparison if (s1.Substring(0, matchList1[i].Index) != s2.Substring(0, matchList2[i].Index)) break;//Character before number is different, directly use string comparison if (matchList1[i].Value == matchList2[i].Value) continue;//Compare the next set of numbers when they are the same int s = matchList1[i].Value.Length - matchList2[i].Value.Length; if (s == 0) break;//Same number of digits, directly using string comparison string temp = ""; if (s > 0) //The purpose of not directly comparing numbers here is to compare strings after numbers. { //When s1 The number length of is greater than s2 When, right s2 And then compare s1 And s2 Character string 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) { //When s1 The number length of is less than s2 When, right s1 And then compare s1 And s2 Character string 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); }
Method use
List<string> list = new List<string>(); list.Add("file(11)"); list.Add("file(22)"); list.Add("writing(11)piece(1)"); list.Add("writing(2)piece(2)"); list.Add("file(3)"); list.Add("file(4)"); list.Sort((m1, m2) => Common.THMethod.FileNameCompare(m1, m2)); list.ForEach(l => Console.WriteLine(l));