[SOLVED] Натуральная сортировка списка файлов (natural sort)

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 452
Благодарностей
564
Баллы
113
Приветствую!
Нужна помощь с кодом C#

В папке в Windows лежат файлы:
1.txt
2.txt
3.txt
...
10.txt
итд

В ZennoPoster получаю список файлов и там сортировка следующая:
1.txt
2.txt
10.txt
И так далее. Мне же нужно получить сортировку файлов, как в Windows.

Узнал, что это называется натуральной сортировкой. Но фиг знает, как её применить в рамках ZennoPoster.
Прошу помощи.
 

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 452
Благодарностей
564
Баллы
113
Нашёл костыли, проверил, работает.
Кому надо, забирайте.

На входе имеем:
1.
10.
1000.
1001.
1011. итд.

На выходе
1.
2.
3.
4.
5.

Вот это в общий код:
C#:
public class NaturalComparer : Comparer<string>, IDisposable
{
    private Dictionary<string, string[]> table;

    public NaturalComparer()
    {
        table = new Dictionary<string, string[]>();
    }

    public void Dispose()
    {
        table.Clear();
        table = null;
    }

    public override int Compare(string x, string y)
    {
        if(x == y)
        {
            return 0;
        }
        string[] x1, y1;
        if(!table.TryGetValue(x, out x1))
        {
            x1 = Regex.Split(x.Replace(" ", ""), "([0-9]+)");
            table.Add(x, x1);
        }
        if(!table.TryGetValue(y, out y1))
        {
            y1 = Regex.Split(y.Replace(" ", ""), "([0-9]+)");
            table.Add(y, y1);
        }

        for(int i = 0; i < x1.Length && i < y1.Length; i++)
        {
            if(x1[i] != y1[i])
            {
                return PartCompare(x1[i], y1[i]);
            }
        }
        if(y1.Length > x1.Length)
        {
            return 1;
        }
        else if(x1.Length > y1.Length)
        {
            return -1;
        }
        else
        {
            return 0;
        }
    }

    private static int PartCompare(string left, string right)
    {
        int x, y;
        if(!int.TryParse(left, out x))
        {
            return left.CompareTo(right);
        }

        if(!int.TryParse(right, out y))
        {
            return left.CompareTo(right);
        }

        return x.CompareTo(y);
    }
}
Так используем в кубике:
C#:
IZennoList textFilePaths = project.Lists["textFilePaths"]; // наш список файлов или другой список

List<string> sortList = new List<string>(textFilePaths); // создаём копию первого списка

// очистка исходного списка
textFilePaths.Clear();

// вызов того, что вписали в общий код
using(NaturalComparer comparer = new NaturalComparer())
{
    sortList.Sort(comparer);
}

// циклом добавляем в исходный список уже отсортированные данные
foreach(string _item in sortList)
{
    textFilePaths.Add(_item);
}
 
Последнее редактирование:

doc

Client
Регистрация
30.03.2012
Сообщения
8 614
Благодарностей
4 602
Баллы
113
C#:
IZennoList textFilePaths = project.Lists["textFilePaths"]; // наш список файлов или другой список
List<string> sortList = new List<string>(textFilePaths); // создаём копию первого списка
// очистка исходного списка
textFilePaths.Clear();

sortList.OrderBy(x=>int.Parse(Path.GetFileNameWithoutExtension(x))).ToList().ForEach(x=>textFilePaths.Add(x));
 

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 452
Благодарностей
564
Баллы
113
C#:
IZennoList textFilePaths = project.Lists["textFilePaths"]; // наш список файлов или другой список
List<string> sortList = new List<string>(textFilePaths); // создаём копию первого списка
// очистка исходного списка
textFilePaths.Clear();

sortList.OrderBy(x=>int.Parse(Path.GetFileNameWithoutExtension(x))).ToList().ForEach(x=>textFilePaths.Add(x));
Код не работает из коробки ваш.
Входная строка имела не верный формат.
 

doc

Client
Регистрация
30.03.2012
Сообщения
8 614
Благодарностей
4 602
Баллы
113

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 452
Благодарностей
564
Баллы
113
будет работать если список полных имён файлов
Всмысле?

У меня вот так:
upload_2018-7-7_8-37-47.png

Полные пути к файлам. А как нужно?

Если ваш сниппет сработает, то я буду использовать его. Лучше меньше строчек кода, но возможности разбираться нет.
 

doc

Client
Регистрация
30.03.2012
Сообщения
8 614
Благодарностей
4 602
Баллы
113
В папке в Windows лежат файлы:
1.txt
2.txt
3.txt
...
10.txt
итд

В ZennoPoster получаю список файлов и там сортировка следующая:
1.txt
2.txt
10.txt
сначала ты описываешь один формат имени файлов, а на скрине уже всё по-другому
 

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 452
Благодарностей
564
Баллы
113

doc

Client
Регистрация
30.03.2012
Сообщения
8 614
Благодарностей
4 602
Баллы
113
C#:
IZennoList textFilePaths = project.Lists["textFilePaths"]; // наш список файлов или другой список
List<string> sortList = new List<string>(textFilePaths); // создаём копию первого списка
// очистка исходного списка
textFilePaths.Clear();
sortList.OrderBy(x=>int.Parse(Regex.Match(x, @"(?<=\\)\d+(?=[^\\]+$)").Value)).ToList().ForEach(x=>textFilePaths.Add(x));
 

Meteorburn

Client
Регистрация
23.05.2016
Сообщения
1 452
Благодарностей
564
Баллы
113
C#:
IZennoList textFilePaths = project.Lists["textFilePaths"]; // наш список файлов или другой список
List<string> sortList = new List<string>(textFilePaths); // создаём копию первого списка
// очистка исходного списка
textFilePaths.Clear();
sortList.OrderBy(x=>int.Parse(Regex.Match(x, @"(?<=\\)\d+(?=[^\\]+$)").Value)).ToList().ForEach(x=>textFilePaths.Add(x));
Отлично, теперь работает!
Спасибо!
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)