Monday, 1 December 2014

Order strings by name, handling numbers naturally

Here's how to sort a collection of strings, such as file names, with numbers being handled naturally. The example is in C#.NET, but the concept is portable.

private static readonly int INT_MAX_DIGITS = Int32.MaxValue.ToString().Length;
public static string ConvertForNaturalOrdering(string path)
{
 var sb = new StringBuilder();
 var digitCache = new StringBuilder();
 foreach (char ch in path)
 {
  if (Char.IsDigit(ch))
  {
   digitCache.Append(ch);
   continue;
  }
  if (digitCache.Length > 0)
  {
   sb.Append(digitCache.ToString().PadLeft(INT_MAX_DIGITS, '0'));
   digitCache.Length = 0;
  }
  sb.Append(ch);
 }
 if (digitCache.Length > 0)
  sb.Append(digitCache.ToString().PadLeft(INT_MAX_DIGITS, '0'));
 return sb.ToString();
}

Here is how the method can be used.

var sorted =
 from path in new[] { "aab2", "aaa10", "aaa2", "aaa1 1" }
 orderby ConvertForNaturalOrdering(path)
 select path;

The 'sorted' enumeration will be in this order:
 "aaa1 1", "aaa2", "aaa10", "aab2"

No comments:

Post a Comment