Сортировка массива имен папок, таких как Windows Explorer (по номерам и по алфавиту) - VB.NET - PullRequest
16 голосов
/ 23 июня 2010

Я убиваю себя и дегидратирую, пытаясь отсортировать этот массив.

У меня есть массив, содержащий каталоги, сгенерированные;

Dim Folders () As String = Directory.GetDirectories (RootPath)

Мне нужно, чтобы они были отсортированы, чтобы они выглядели как в Windows Explorer в Win7 / Vista.- в числовом и алфавитном порядке по именам папок.

Имена папок содержат как буквы, так и цифры, иногда только буквы или только цифры.

Простая сортировка Array.Sort (папки) приводит к

C:\inetpub\wwwroot\rootpath\1
C:\inetpub\wwwroot\rootpath\10
C:\inetpub\wwwroot\rootpath\100
C:\inetpub\wwwroot\rootpath\1004
C:\inetpub\wwwroot\rootpath\101
C:\inetpub\wwwroot\rootpath\11
C:\inetpub\wwwroot\rootpath\12
C:\inetpub\wwwroot\rootpath\2
C:\inetpub\wwwroot\rootpath\3
C:\inetpub\wwwroot\rootpath\4
C:\inetpub\wwwroot\rootpath\5
C:\inetpub\wwwroot\rootpath\6
C:\inetpub\wwwroot\rootpath\7
C:\inetpub\wwwroot\rootpath\8
C:\inetpub\wwwroot\rootpath\87skjnd
C:\inetpub\wwwroot\rootpath\89sdf93kmw3
C:\inetpub\wwwroot\rootpath\9
C:\inetpub\wwwroot\rootpath\ad
C:\inetpub\wwwroot\rootpath\bin
C:\inetpub\wwwroot\rootpath\dark
C:\inetpub\wwwroot\rootpath\erk
C:\inetpub\wwwroot\rootpath\jkh23978yoaslkd3
C:\inetpub\wwwroot\rootpath\lk2309as
C:\inetpub\wwwroot\rootpath\work
C:\inetpub\wwwroot\rootpath\zone

То, что я хочу иметь (и что отображает проводник Windows) - это ...

C:\inetpub\wwwroot\rootpath\1
C:\inetpub\wwwroot\rootpath\2
C:\inetpub\wwwroot\rootpath\3
C:\inetpub\wwwroot\rootpath\4
C:\inetpub\wwwroot\rootpath\5
C:\inetpub\wwwroot\rootpath\6
C:\inetpub\wwwroot\rootpath\7
C:\inetpub\wwwroot\rootpath\8
C:\inetpub\wwwroot\rootpath\9
C:\inetpub\wwwroot\rootpath\10
C:\inetpub\wwwroot\rootpath\11
C:\inetpub\wwwroot\rootpath\12
C:\inetpub\wwwroot\rootpath\87skjnd
C:\inetpub\wwwroot\rootpath\89sdf93kmw3
C:\inetpub\wwwroot\rootpath\100
C:\inetpub\wwwroot\rootpath\101
C:\inetpub\wwwroot\rootpath\1004
C:\inetpub\wwwroot\rootpath\ad
C:\inetpub\wwwroot\rootpath\bin
C:\inetpub\wwwroot\rootpath\dark
C:\inetpub\wwwroot\rootpath\erk
C:\inetpub\wwwroot\rootpath\jkh23978yoaslkd3
C:\inetpub\wwwroot\rootpath\lk2309as
C:\inetpub\wwwroot\rootpath\work
C:\inetpub\wwwroot\rootpath\zone

Я гуглил и обнаружил, что нужно написать класс, который использует IComparable для сортировки элементов.Быть сверхновым ... Я действительно не знаю, как это можно сделать.Большинство примеров, на которые я смотрел, имели многомерные массивы и ключи: S ...

было бы еще лучше, если бы сортировку можно было применять к массиву имен файлов (вместо foldernames) или массиву, содержащему как папки, так и файлы.... в этом случае отсортированные папки появляются вверху, а отсортированные файлы ниже ... это вообще возможно?

Любая помощь будет сильно оценена ...: D спасибо.

Ответы [ 2 ]

25 голосов
/ 23 июня 2010

Вам потребуется реализовать IComparer, а не создавать класс, реализующий IComparable. Разница в том, что IComparer обладает необходимыми «знаниями» для сравнения двух объектов, тогда как IComparable реализуется классом, который знает, как сравнивать себя с чем-то другим.

И способ, которым проводник Windows сортирует имена файлов, использует функцию с именем StrCmpLogicalW . Вы можете использовать эту функцию в своем собственном IComparer, чтобы получить то же поведение сортировки, что и Windows Explorer. Эта функция обрабатывает числовые части строк как числа, так что 9 сортируется до 10.

public class MyComparer : IComparer<string> {

    [DllImport("shlwapi.dll", CharSet=CharSet.Unicode, ExactSpelling=true)]
    static extern int StrCmpLogicalW(String x, String y);

    public int Compare(string x, string y) {
        return StrCmpLogicalW(x, y);
    }

}

Array.Sort(unsortedNames, new MyComparer());

И так как я только что заметил, вопрос помечен VB ... Простите мой ржавый VB!

Public Class MyComparer
    Implements IComparer(Of String)

    Declare Unicode Function StrCmpLogicalW Lib "shlwapi.dll" ( _
        ByVal s1 As String, _
        ByVal s2 As String) As Int32

    Public Function Compare(Byval x as String, Byval y as String) As Integer _
        Implements System.Collections.Generic.IComparer(Of String).Compare

        Return StrCmpLogicalW(x, y)

    End Function

End Class
1 голос
/ 23 июня 2010

Array.Sort также имеет параметр IComparer, вы можете переопределить поведение сортировки, если вам не нравится значение по умолчанию.см. метод Array.Sort (T [], IComparer) как это сделать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...