Sorting arrays numerically and alphabetically(like Windows Explorer) without using StrCmpLogicalW or shlwapi.dll - ASP.NET VB

后端 未结 1 1309
忘了有多久
忘了有多久 2020-12-07 00:05

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

相关标签:
1条回答
  • 2020-12-07 00:11

    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:

    alt text

    0 讨论(0)
提交回复
热议问题