Answer the question
In order to leave comments, you need to log in
C#. What is the correct way to get a list of files from a folder in the correct order?
Hello!
Backfill question...
I get a list of files from a folder.
Tried it like that
var testFiles = Directory.EnumerateFiles(solutionDirectory + @"\samples");
1.jpg
2.jpg
3.jpg
4.jpg
5.jpg
6.jpg
6721086-1.jpg
6721086-2.jpg
6721086-3.jpg
7.jpg
8.jpg
9.jpg
Answer the question
In order to leave comments, you need to log in
Windows already has a ready-made function that performs a natural string comparison, it's better to use it. This function splits a string into numeric and string parts and searches for these parts with each other, and compares the numeric parts as numbers, and the string parts - alphabetically.
var testFiles = Directory.EnumerateFiles(solutionDirectory + @"\samples");
var sortedTestFiles1 = testFiles.OrderBy(x => x, new NaturalComparer());
// или
var sortedTestFiles2 = testFiles.ToList();
sortedTestFiles2.Sort(new NaturalComparer());
/// <summary>
/// Натуральное сравнение строк
/// </summary>
public class NaturalComparer : IComparer<string>
{
/// <summary>
/// Вызов WinApi-функции для натурального сравнения строк
/// </summary>
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern int StrCmpLogicalW(string psz1, string psz2);
/// <summary>
/// Натуральное сравнение строк
/// </summary>
/// <param name="x">Первая строка</param>
/// <param name="y">Вторая строка</param>
/// <returns>Сравнивает две строки, возвращая -1, 0 или 1</returns>
public static int Compare(string x, string y)
{
return StrCmpLogicalW(x, y);
}
/// <summary>
/// Натуральное сравнение строк
/// </summary>
/// <param name="x">Первая строка</param>
/// <param name="y">Вторая строка</param>
/// <returns>Сравнивает две строки, возвращая -1, 0 или 1</returns>
int IComparer<string>.Compare(string x, string y)
{
return StrCmpLogicalW(x, y);
}
}
The way you see the files in the folder is sorted by File Explorer and does not say at all how they are stored or in what order they were added to the folder. If you want to see in the same order as in the explorer, then sort the result by the same parameters
testFiles.OrderBy(f => f.Name)
C# sorts strings lexicographically, and explorer uses Natural Sort. Here is what I googled for Natural Sort in C# in a minute:
public static IOrderedEnumerable<T> OrderByAlphaNumeric<T>(this IEnumerable<T> source, Func<T, string> selector)
{
int max = source
.SelectMany(i => Regex.Matches(selector(i), @"\d+").Cast<Match>().Select(m => (int?)m.Value.Length))
.Max() ?? 0;
return source.OrderBy(i => Regex.Replace(selector(i), @"\d+", m => m.Value.PadLeft(max, '0')));
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question