T
T
TechNOIR2019-02-13 01:06:10
C++ / C#
TechNOIR, 2019-02-13 01:06:10

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");

and so
about-windows.ru/programmirovanie/programmirovanie...
I get in this order:
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

And in the folder they are in this order:
5c63433acb249974285671.png
Here's how to get it in exactly the same order as in the picture?
thanks in advance

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
Alexey Pavlov, 2019-02-13
@TechNOIR

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);
    }
}

E
eRKa, 2019-02-13
@kttotto

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)

A
Alexeytur, 2019-02-13
@Alexeytur

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 question

Ask a Question

731 491 924 answers to any question