I just got a support task where I’m pulling data from an API and need to sort the items based on a chapter like key. The data looks like this:
- ST.1.1
- ST.1.2
- ST.1.10
- ST.2.20a
The data is coming back random, and if I do a pure alfanumeric sorter, then ST.1.10 will sort above ST.1.2, which is lexically incorrect. Since I know I will never have numbers above three digits (ST.999.999), I figured I could sort it all by padding the numbers. This is the solution I ended up with, and if you have a smarter one let me know :)
I’m matching right to left in the regular expression as this makes it easier to replace the string as indexes are not changed when inserting characters.
class Program { static void Main() { var demo = new List<string> { "ST.1.1", "ST.1.10", "ST.1.3c", "ST.1.3a", "ST.1.2" }; demo = demo.OrderBy(PadName).ToList(); demo.ForEach(Console.WriteLine); //output is: ST.1.1 ST.1.2 ST.1.3a ST.1.3c ST.1.10 } static readonly Regex _reNumber = new Regex(@"\d+", RegexOptions.Compiled | RegexOptions.RightToLeft); static string PadName(string name) { foreach (Match match in _reNumber.Matches(name)) { string newNumber = match.Value.PadLeft(3, '0'); name = name.Remove(match.Index, match.Length) .Insert(match.Index, newNumber); } return name; } }