# Windows Explorer Natural Order

Currently there are a list of notebooks in Windows that I am processing in a folder. Ideally I would like the notebooks to be concated in the same order as how they display in Windows Explorer.

I found the question Sort Strings By Natural Order, but none of the answers seem to use the same technique as Windows Explorer. After reading What is the first character in the sort order used by Windows Explorer?, it appears that Windows has an internal function that could be used to naturally sort the filenames. I plan to run this only on Windows, so it is okay if it depends on OS-specific functions, though a pure Mathematica way would be nice.

I believe that Windows sorts the files based on ASCII order unless a number is encountered. Ideally I am looking for a function that sorts a list of names into the following order when run. None of the answers linked above correctly order the names below.

{"Ie4 01", "Ie4!01", "Ie4_01", "Ie4_128", "Ie5", "Ie6", "Ie401sp2",
"Ie501sp2"}

Ie4 01
Ie4!01
Ie4_01
Ie4_128
Ie5
Ie6
Ie401sp2
Ie501sp2

-
Could you perhaps specify the kind of ordering you are after to make the question self-contained? –  Yves Klett Dec 27 '13 at 10:42
(1) Please include some example strings/names where the Windows ordering does not match the ordering given by methods in the linked Q&A. (2) How robust does this need to be? Since you don't want to use the Windows sorting itself you are asking for a reimplementation of that sort ordering, and unless the exact specification is available it will be hard to confirm that it is entirely uniform. –  Mr.Wizard Dec 27 '13 at 11:50
@YvesKlett I have added an example which I believe demonstrates all the necessary issue encountered with the linked Q&As. –  Liam William Dec 27 '13 at 18:59
You can call the DLL function that does the sorting: msdn.microsoft.com/en-us/library/bb759947%28VS.85%29.aspx –  Ajasja Dec 27 '13 at 19:25
@Mr.Wizard I Added an example which I believe demonstrates the issue that are encountered with the linked Q&As. I striked through the restraint of using Windows sorting because I'm not particularly concerned about running the script on Linux or OSX. –  Liam William Dec 27 '13 at 20:07

You can call the windows function that does the sorting directly. The function is StrCmpLogicalW. Note that this is not a cross-platform solution:)

Here is a short example:

Needs["NETLink"];
naturalOrder =
DefineDLLFunction["StrCmpLogicalW", "Shlwapi.dll",
"int", {"string", "string"}, MarshalStringsAs -> "Unicode"];

strings = {"Ie501sp2", "Ie4!01", "Ie4 01", "Ie4_01",
"Ie4_128", "Ie5", "Ie6", "Ie401sp2"};
Sort[strings, naturalOrder[#1, #2] == -1 &] //Column

(*
Ie4 01
Ie4!01
Ie4_01
Ie4_128
Ie5
Ie6
Ie401sp2
Ie501sp2
*)

-
Great except it doesn't seem to match Windows Explorer. :) I have no idea why just yet. –  Liam William Dec 27 '13 at 20:42
The hat becomes you (^_-) –  Yves Klett Dec 27 '13 at 20:45
I just tried all StrCmp on this page. Map[( naturalOrder = DefineDLLFunction[#, "Shlwapi.dll", "int", {"string", "string"}]; strings = FileNames[]; Sort[strings, naturalOrder[#1, #2] == 1 &]) &, {"StrCmpW", "StrCmpCW", "StrCmpIW", "StrCmpICW", "StrCmpLogicalW", "StrCmpNW", "StrCmpNCW", "StrCmpNIW", "StrCmpNICW"} ] Non of them seem to match. –  Liam William Dec 27 '13 at 21:00
@LiamWilliam Sorry, forgot the MarshalStringsAs` option. –  Ajasja Dec 27 '13 at 21:30
@YvesKlett Hehe, thanks. It does look kind of regal, doesn't it:) –  Ajasja Dec 27 '13 at 22:57