Sorting list of string paths in VB.NET
I would like to sort a list of strings which represent paths. The sort result will do have a hierarchical order.
What I mean is: for each directory path, I want to list all files in that path (alphabeticaly or not doesn't matter) in first time. Then, each subdirectory path will be listed. For each subdirectory, I want all files... and so on.
Here is an example:
(Before)
emule/changelog.txt
emule/config/
emule/config/adresses.dat
emule/config/nodes.dat
emule/config/webservices.dat
emule/eMule.tmpl
emule/eMule_Chicane.tmpl
emule/license.txt
emule/license-GER.txt
emule/readme.txt
emule/Skin/
emule/Skin/Daan-V2-8.eMuleSkin.ini
emule/Skin/DaanV2-8/
emule/Skin/DaanV2-8/back.ICO
emule/Skin/DaanV2-8/WebServer.ico
emule/Template.eMuleSkin.ini
emule/webserver/
emule/webserver/add_server.gif
emule/webserver/arrow_down.gif
emule/webserver/arrow_right.gif
emule/webserver/yellow.gif
emule/emule.exe
(After)
emule/changelog.txt
emule/emule.exe
emule/eMule.tmpl
emule/eMule_Chicane.tmpl
emule/license.txt
emule/license-GER.txt
emule/readme.txt
emule/Template.eMuleSkin.ini
emule/config/
emule/config/adresses.dat
emule/config/nodes.dat
emule/config/webservices开发者_JAVA技巧.dat
emule/Skin/
emule/Skin/Daan-V2-8.eMuleSkin.ini
emule/Skin/DaanV2-8/
emule/Skin/DaanV2-8/back.ICO
emule/Skin/DaanV2-8/WebServer.ico
emule/webserver/
emule/webserver/add_server.gif
emule/webserver/arrow_down.gif
emule/webserver/arrow_right.gif
emule/webserver/yellow.gif
I tried many solutions like Array.Sort() with a custom IComparable function.
Do you have any idea? Thanks so much.
EDIT: here is my IComparable method
zipEntries.Sort(AddressOf compareZipEntryFilenames)
Private Function compareZipEntryFilenames(ByVal x As Object, ByVal y As Object) As Integer
Dim one As String = CType(x, ZipEntry).FileName
Dim two As String = CType(y, ZipEntry).FileName
If Path.GetDirectoryName(one) = Path.GetDirectoryName(two) Then
Return String.Compare(one, two)
Else
Select Regex.Matches(one, "/").Count.CompareTo(Regex.Matches(two, "/").Count)
Case -1 'one has less / than two; so one then two
Return -1
Case 1 'one has more / than two; so two then one
Return 1
Case Else ' = 0, same number of /; so alphabetical sorting
Return String.Compare(one, two)
End Select
End If
End Function
Turns out to be as simple as:
Private Function compareZipEntryFilenames(ByVal x As ZipEntry, ByVal y As ZipEntry) As Integer
Dim res As Integer = String.Compare(Path.GetDirectoryName(x.FileName), Path.GetDirectoryName(y.FileName))
If res = 0 Then
Return String.Compare(x.FileName, y.FileName)
Else
Return res
End If
End Function
Insert the below into the class in which the sort occurs, and then use zipEntries.Sort(new PathComparer)
private class PathComparer
implements IComparer
Public Function compareZipEntryFilenames(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
Dim one As String = CType(x, ZipEntry).FileName
Dim two As String = CType(y, ZipEntry).FileName
If Path.GetDirectoryName(one) = Path.GetDirectoryName(two) Then
Return String.Compare(one, two)
Else
Select Regex.Matches(one, "/").Count.CompareTo(Regex.Matches(two, "/").Count)
Case -1 'one has less / than two; so one then two
Return -1
Case 1 'one has more / than two; so two then one
Return 1
Case Else ' = 0, same number of /; so alphabetical sorting
Return String.Compare(one, two)
End Select
End If
End Function
end class
精彩评论