[SalesForce] Sort with field of type String containing numbers and letters both

What is the best way to sort a List of String containing letters and numbers as values?

I have tried couple of ways to sort, but with nothing I could make it work.

  1. Using a sort method of list
  2. Using comparable interface

Small example what I am trying to achieve

List<String> strList = new List<String>{'1 test', '2 test', '10 test', '13 test'};

With every method I use for sorting i get the result like

{(1 test, 10 test, 13 test, 2 test)}

However I am trying to achieve {(1 test, 2 test, 10 test, 13 test)}

I know it is happening because salesforce do the sorting lexicographically. But is there a way to achieve what I am after ?

Best Answer

Given the pattern you have described, you could certainly try to parse out the starting number and sort on that.

public class NumericString implements Comparable
{
    final Integer numericValue;
    public final String value;
    public NumericString(String value)
    {
        this.value = value;
        this.numericValue = getStartingDigits(value);
    }
    public Integer compareTo(Object instance)
    {
        NumericString that = (NumericString)instance;
        if (this.numericValue == null) return 1;
        if (that.numericValue == null) return -1;
        return this.numericValue - that.numericValue;
    }

    public static Integer getStartingDigits(String value)
    {
        if (String.isNotBlank(value))
        {
            try
            {
                return Integer.valueOf(value.splitByCharacterType()[0]);
            }
            catch (TypeException tex) { /*NaN*/ }
        }
        return null;
    }
}

The above should be simpler with regular expressions, but I couldn't get them to work. I also put nulls last, but you could put them first by reversing this and that in your null checks.