Wednesday, February 10, 2016

A small alfanumeric sorter with numeric padding

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();
        //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;