C# Sort files by natural number ordering in the name?
I have files in directory like that
0-0.jpeg
0-1.jpeg
0-5.jpeg
0-9.jpeg
0-10.jpeg
0-12.jpeg
....
when i loading files:
FileInfo[] files = di.GetFiles();
They getting in wrong order (they should go like above):
0-0.jpeg
0-1.jpeg
0-10.jpeg
0-12.jpeg
0-5.jpeg
0-9.jpeg
How to fix that?
I was trying to sort them but no way:
1) Array.Sort(files, (f1, f2) => f1.Name.CompareTo(f2.Name));
2) Array.Sort(files, (x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.Name, y.Name));
I know this might be late, but here is another solution which works perfectly
FileInfo[] files = di.GetFiles().OrderBy(n => Regex.Replace(n.Name, @"\d+", n => n.Value.PadLeft(4, '0')));
Using Regex replace in the OrderBy Clause
:
Regex.Replace(n.Name, @"\d+", n => n.Value.PadLeft(4, '0'))
So what this does, it pads
the numeric values in the file name with a length of 4 chars in each number:
0-0.jpeg -> 0000-0000.jpeg
0-1.jpeg -> 0000-0001.jpeg
0-5.jpeg -> 0000-0005.jpeg
0-9.jpeg -> 0000-0009.jpeg
0-10.jpeg -> 0000-0010.jpeg
0-12.jpeg -> 0000-0012.jpeg
But this only happens in the OrderBy
clause, it does not touch the original file name in any way. The order you will end up with in the array is the "human natural" order.
Alphabetically, the "wrong" order is in fact correct. If you want it sorted numerically then you'll need to either:
- convert the filenames to a list of numeric numbers and sort them
- name the files in such a way that alphabetic and numeric sorting are the same (0-001.jpeg and 0-030.jpg)
- rely on the file creation time to sort (presuming the files were created in order).
See the answer to Sorting Directory.GetFiles() for an example of #3.