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;
}
}