按字母顺序对目录路径进行排序

时间:2020-08-17 06:05:30

标签: vb.net sorting

下面的代码用于在vb.net中对目录进行排序。

Dim a As New List(Of String)
            a.Add("a\b\c")
            a.Add("a\b\c\d")
            a.Add("a\b\c d")
            a.Add("a\b\c d\e")
            a.Add("a\b\c\d\f")

            a.Sort(Function(x, Y) (x).CompareTo((Y)))
        
        

结果:

        a\b\c
        a\b\c d
        a\b\c d\e
        a\b\c\d
        a\b\c\d\f
        
        

在结果列表中,带有空格的目录位于“ \”之前。

有超过1500000个子目录和文件 排序大约需要50秒(默认方法) 我们尝试的所有其他方法都至少需要400秒。

如何按字母顺序对目录路径进行排序? 有没有内置的方法可以在空格前考虑反斜杠?

1 个答案:

答案 0 :(得分:0)

您需要将路径分解为单独的文件夹名称,然后依次比较每个文件夹名称,直到发现差异为止。如果没有差异,则可以使用长度来区分,即,更高级别的文件夹位于第一位。

a.Sort(Function(x, y)
           Dim xFolderNames As New List(Of String)
           Dim yFolderNames As New List(Of String)

           'Split first path into folder names.
           Do Until String.IsNullOrEmpty(x)
               xFolderNames.Insert(0, Path.GetFileName(x))
               x = Path.GetDirectoryName(x)
           Loop

           'Split second path into folder names.
           Do Until String.IsNullOrEmpty(y)
               yFolderNames.Insert(0, Path.GetFileName(y))
               y = Path.GetDirectoryName(y)
           Loop

           Dim result = 0

           'Compare up to as many folders as are in the shortest path.
           For i = 0 To Math.Min(xFolderNames.Count, yFolderNames.Count) - 1
               result = xFolderNames(i).CompareTo(yFolderNames(i))

               If result <> 0 Then
                   'A difference has been found.
                   Exit For
               End If
           Next

           If result = 0 Then
               'No difference was found so put the shortest path first.
               result = xFolderNames.Count.CompareTo(yFolderNames.Count)
           End If

           Return result
       End Function)

为了很好地衡量,这是一个封装该功能的类:

Imports System.Collections.ObjectModel
Imports System.IO

Public Class FileSystemPath
    Implements IComparable, IComparable(Of FileSystemPath)

    Public ReadOnly Property FullPath As String

    Public ReadOnly Property PartialPaths As ReadOnlyCollection(Of String)

    Public Sub New(fileOrFolderPath As String)
        FullPath = fileOrFolderPath

        Dim partialPaths As New List(Of String)

        Do Until String.IsNullOrEmpty(fileOrFolderPath)
            partialPaths.Insert(0, Path.GetFileName(fileOrFolderPath))
            fileOrFolderPath = Path.GetDirectoryName(fileOrFolderPath)
        Loop

        Me.PartialPaths = New ReadOnlyCollection(Of String)(partialPaths)
    End Sub

    Public Function CompareTo(obj As Object) As Integer Implements IComparable.CompareTo
        Return CompareTo(DirectCast(obj, FileSystemPath))
    End Function

    Public Function CompareTo(other As FileSystemPath) As Integer Implements IComparable(Of FileSystemPath).CompareTo
        Dim result = 0

        'Compare up to as many folders as are in the shortest path.
        For i = 0 To Math.Min(PartialPaths.Count, other.PartialPaths.Count) - 1
            result = PartialPaths(i).CompareTo(other.PartialPaths(i))

            If result <> 0 Then
                'A difference has been found.
                Exit For
            End If
        Next

        If result = 0 Then
            'No difference was found so put the shortest path first.
            result = PartialPaths.Count.CompareTo(other.PartialPaths.Count)
        End If

        Return result
    End Function


    Public Overrides Function ToString() As String
        Return FullPath
    End Function

End Class

只需更改一下代码就可以使用它:

Dim a As New List(Of FileSystemPath)
a.Add(New FileSystemPath("a\b\c"))
a.Add(New FileSystemPath("a\b\c\d"))
a.Add(New FileSystemPath("a\b\c d"))
a.Add(New FileSystemPath("a\b\c d\e"))
a.Add(New FileSystemPath("a\b\c\d\f"))

a.Sort()

Console.WriteLine(String.Join(Environment.NewLine, a))
Console.ReadLine()