I created a sorter that StrCmpLogicalW / shlwapi.dll. unfortunately it causes errors on partial trust environments. I am in a really bad need of a solution that does not use 'shlwapi.dll' or StrCmpLogicalW and works in the same fashion.
Here's the sorter t开发者_如何学Chat causes the error.
Public Class nvSorter
Implements IComparer(Of String)
Declare Unicode Function StrCmpLogicalW Lib "shlwapi.dll" ( _
ByVal s1 As String, _
ByVal s2 As String) As Int32
Public Function Compare(ByVal x As String, ByVal y As String) As Integer
Implements System.Collections.Generic.IComparer(Of String).Compare
Return StrCmpLogicalW(x, y)
End Function
End Class
This should work:
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Filenames() As String = New String() {"0", "1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "2", "20", "3", "4", "5", "6", "7", "8", "9"}
Array.Sort(Filenames, New CustomComparer)
MessageBox.Show(String.Join(",", Filenames))
End Sub
End Class
Public Class CustomComparer
Implements IComparer(Of String)
Private Position As Integer
Private Order As Integer = 1
Public Sub New(Optional ByVal Ascending As Boolean = True)
If Not Ascending Then
Order = -1
End If
End Sub
Private Shared Function EmptyText(ByVal s As String) As Boolean
Return String.Empty.Equals(s)
End Function
Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements System.Collections.Generic.IComparer(Of String).Compare
Dim res1 As New List(Of String)(System.Text.RegularExpressions.Regex.Split(x, "(\d+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
Dim res2 As New List(Of String)(System.Text.RegularExpressions.Regex.Split(y, "(\d+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
res1.RemoveAll(AddressOf EmptyText)
res2.RemoveAll(AddressOf EmptyText)
Position = 0
For Each xstr As String In res1
If res2.Count > Position Then
If Not IsNumeric(xstr) AndAlso Not IsNumeric(res2(Position)) Then
Dim intresult As Integer = String.Compare(xstr, res2(Position), True)
If intresult <> 0 Then
Return intresult * Order
Else
Position += 1
End If
ElseIf IsNumeric(xstr) And Not IsNumeric(res2(Position)) Then
Return -1 * Order
ElseIf Not IsNumeric(xstr) And IsNumeric(res2(Position)) Then
Return 1 * Order
ElseIf IsNumeric(xstr) And IsNumeric(res2(Position)) Then
Dim res As Integer = Decimal.Compare(Decimal.Parse(xstr), Decimal.Parse(res2(Position)))
If res = 0 Then
Position += 1
Else
Return res * Order
End If
End If
Else
Return -1 * Order
End If
Next
Return 1 * Order
End Function
End Class
The result of the above sorting example of "0", "1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "2", "20", "3", "4", "5", "6", "7", "8", "9"
is:
精彩评论