我有 DirectoryInfo 列表,其中包含以下文件夹名称:
80's
90's
2000
2001
问题是“ IO.Directory.GetDirectories ”函数返回通用Microsoft排序,因此我的列表按如下顺序排序:
2000
2001
80's
90's
我知道冒泡排序的算法(我总是看到FOR的用法并生成其他时间对象,我不喜欢我见过的任何冒泡排序方法)我希望如果可以简化冒泡排序使用LINQ或其他改进的方法,但不能用于在内存中创建额外的对象。
如何通过其Directory.Name属性 冒泡排序 列表(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
答案 0 :(得分:1)
我使用Telerik的in referenced question翻译了代码online converter。它也适用于您的情况。
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
答案 1 :(得分:1)
对@ L.B解决方案的修改很少,我希望这有助于其他人:
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