.NET natural sort, a possible solution.

You have a list of items, let’s say 20 elements, starting at 1, until 20 (inclusive). We shuffle the list and we try to sort it.

  1. List<string> normalDotNetSort = GiveMeANewList();

The code to create the list:

  1. private static List<string> GiveMeANewList()
  2. {
  3.     List<string> list = new List<string>();
  4.  
  5.     for (int i = 1; i <= 20; i++)
  6.     {
  7.         list.Add(string.Format("{0}", i));
  8.     }
  9.  
  10.     return list.MixList();
  11. }

MixList just shuffles the list.

We’re using a normal Generic List and to sort, let’s use the Sort method, and write it to the console:

  1. normalDotNetSort.Sort();
  2. normalDotNetSort.ForEach(Console.WriteLine);

What would be the result?

.

.

.

.

.

.

.

.

.

.

.

.

.

1
10
11
12
13
14
15
16
17
18
19
2
20
3
4
5
6
7
8
9

That’s not what we wanted, but it is what we told the code to do. It first sorts on the first character, and then on the second (and so on…). That’s why 19 takes precedence of 2, since 1 < 2.

How do we fix this?

There is a little gem in the shlwapi.dll, namely StrCmpLogicalW. Since this is a native function we need to do a DllImport to expose the function to our C# code:

  1. public static class SafeNativeMethods
  2. {
  3.     [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
  4.     public static extern int StrCmpLogicalW(string psz1, string psz2);
  5. }

Now we can use this function in our own string comparer:

  1. public sealed class NaturalStringComparer : IComparer<string>
  2. {
  3.     #region IComparer<string> Members
  4.  
  5.     public int Compare(string x, string y)
  6.     {
  7.         return SafeNativeMethods.StrCmpLogicalW(x, y);
  8.     }
  9.  
  10.     #endregion
  11. }

And use this comparer to sort our list:

  1. List<string> interopSort = GiveMeANewList();
  2. interopSort.Sort(new NaturalStringComparer());
  3. interopSort.ForEach(Console.WriteLine);

And the result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

Much better no?

2 replies on “.NET natural sort, a possible solution.”

  1. Can I just say, that after hours of searching for what I thought would have been so obvious that it’d have been implemented directly into the framework – THANK YOU.

    I really have no idea why “natural sort” just isn’t a part of all languages.

Comments are closed.