0

我有一个DirectoryInfo列表,其中包含如下文件夹名称:

80's
90's
2000
2001

问题是“ IO.Directory.GetDirectories ”函数返回通用 Microsoft 排序,因此我的列表排序如下:

2000
2001
80's
90's

我知道冒泡排序的算法(我总是看到 FOR 的用法并生成其他时间对象,我不喜欢我见过的任何冒泡排序方法),我希望是否可以使用 LINQ 简化冒泡排序或其他改进的方法,但不是因为既不在内存中创建额外的对象。

如何通过 Directory.Name 属性对List(Of DirectoryInfo)进行冒泡排序?(显然我想保留 DirectoryInfo 对象,而不是返回几个排序的字符串),也可能在不使用 LINQ 扩展重新分配列表的情况下对其进行冒泡排序?

更新:

如果有人需要信息,这是我用来获取 DirectoryInfo 列表的功能:

' Get Folders
Private Function Get_Folders(ByVal directory As String, ByVal recursive As Boolean) As List(Of IO.DirectoryInfo)
    Dim searchOpt As IO.SearchOption = If(recursive, IO.SearchOption.AllDirectories, IO.SearchOption.TopDirectoryOnly)
    Return IO.Directory.GetDirectories(directory, "*", searchOpt).Select(Function(p) New IO.DirectoryInfo(p)).ToList
End Function

更新 2

按照关于问题评论的建议,我尝试使用正则表达式和 LINQ 扩展将文件夹名称视为整数来对它们进行排序,仅用几行代码简化所有代码,问题是它失败了,因为我有一些文件夹不能转换为数字,这是一个示例文件夹名称:

80's
90's
2000-2006
2007
2008
Classic
B.S.O
Maquetas

我的问题是,如果我可以在排序时排除 Non-Digits 文件夹,然后将排除的文件夹附加到排序的“整数”文件夹名称,我问这个只是为了不要两次获取所有文件夹以生成两个不同的列表加入他们。

还要注意文件夹名称“2000-2006”,如果我将名称转换为整数,排序时不会得到预期的结果。

那么我如何对列表文件夹名称内容进行冒泡排序,将它们视为什么?,字符串,而不是数字。

Public Class Form1

Dim regex As New System.Text.RegularExpressions.Regex("\D")

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Shown

    For Each folder In Get_Folders("E:\Música\Canciones", False) _
                       .OrderBy(Function(x) Convert.ToInt32(regex.Replace(x.Name, "")))

        MsgBox(folder.Name)
        ' Exception here, because a folder named "B.S.O" and other named as "Classic",
        ' obviouslly they can't be converted to Integer :(

    Next

End Sub

' Get Folders
Private Function Get_Folders(ByVal directory As String, ByVal recursive As Boolean) As List(Of IO.DirectoryInfo)
    Dim searchOpt As IO.SearchOption = If(recursive, IO.SearchOption.AllDirectories, IO.SearchOption.TopDirectoryOnly)
    Return IO.Directory.GetDirectories(directory, "*", searchOpt).Select(Function(p) New IO.DirectoryInfo(p)).ToList
End Function

End Class
4

2 回答 2

1

@LB 解决方案的小修改,我希望这对其他人有帮助:

    Public Shared Function CustomSort(list As List(Of IO.DirectoryInfo)) As List(Of IO.DirectoryInfo)

        Dim maxLen As Integer = list.[Select](Function(s) s.Name.Length).Max()

        Return list.[Select](Function(s) New With { _
            Key .OrgStr = s, _
            Key .SortStr = System.Text.RegularExpressions.Regex.Replace(s.Name, "(\d+)|(\D+)", Function(m) m.Value.PadLeft(maxLen, If(Char.IsDigit(m.Value(0)), " "c, Char.MaxValue))) _
        }).OrderBy(Function(x) x.SortStr).[Select](Function(x) x.OrgStr).ToList
    End Function
于 2013-09-29T15:51:03.183 回答
1

我使用 Telerik 的在线转换器翻译了引用问题中的代码。它也适用于您的情况。

Public Shared Function CustomSort(list As IEnumerable(Of String)) As IEnumerable(Of String)
    Dim maxLen As Integer = list.[Select](Function(s) s.Length).Max()

    Return list.[Select](Function(s) New With { _
        Key .OrgStr = s, _
        Key .SortStr = System.Text.RegularExpressions.Regex.Replace(s, "(\d+)|(\D+)", Function(m) m.Value.PadLeft(maxLen, If(Char.IsDigit(m.Value(0)), " "c, Char.MaxValue))) _
    }).OrderBy(Function(x) x.SortStr).[Select](Function(x) x.OrgStr)
End Function
于 2013-09-29T15:43:42.163 回答