Reputation: 20474
I have a List of DirectoryInfo wich contains folder names like these:
80's
90's
2000
2001
The problem is that the "IO.Directory.GetDirectories" function returns the generic Microsoft Sort so my list is sorted as this:
2000
2001
80's
90's
I know the algorithm to Bubble sort (always I see the usage of a FOR and to generate other temporal objects, I don't like any Bubble sort method I've seen) and I hope if a Bubble Sort can be simplified using LINQ or other improved methods but not a For neither creating extra objects in memory.
How I can Bubble Sort the List(Of DirectoryInfo) by their Directory.Name property ? (obviouslly I want to preserve the DirectoryInfo objects, not to return a couple of sorted Strings), also is possibly to bubble sort it without reallocating the list using LINQ extensions?
UPDATE:
If someone need the information this is the function that I'm using to get the DirectoryInfo list:
' 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
UPDATE 2
Following the suggestions on question comments I'm trying to simplify all the code in just few lines using a regex and LINQ extensions treating the folder names as integers to sort them, the problem is it fails because I have some folders who can't be converted to numbers, this is a example folder names:
80's
90's
2000-2006
2007
2008
Classic
B.S.O
Maquetas
My question is If I can exlude the Non-Digits folders when sorting and then append that excluded folders to the sorted "integer" folder names, I ask this just to don't get all the folders two times to generate two different lists to join them.
Also notice the folder name "2000-2006", if I convert the name to integer I wouldn't get the expected result when sorting.
So just how I could Bubble sort the list folder name content treating them as what are?, strings, not numbers.
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
Upvotes: 0
Views: 1580
Reputation: 20474
Little modification of @L.B solution, I hope this helps someone else:
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
Upvotes: 1
Reputation: 116168
I translated the code in referenced question using Telerik's online converter. It works for your case too.
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
Upvotes: 1