如何按 VB.NET 中的版本或点分隔的数组列表排序

How to order an arraylist by versions or dot delimited in VB.NET

我的数组列表中有这样的输入:

1
1.1
1.1.1
1.1.1.1
1.1.2
1.10
1.11
1.2
1.9

我想对其进行排序,得到的结果如下所示:

1
1.1
1.1.1
1.1.1.1
1.1.2
1.2
1.9    
1.10
1.11

我找到了其他语言的可能解决方案,但我很难理解它们。 我有这个函数可以读取没有扩展名的文件夹的文件名,但我不知道如何对它们进行排序(我试图将它们视为小数,但没有用)。

    Function GetVersions(ByVal mypath As String) As ArrayList
    Dim Versions As New ArrayList

    For Each Ver As String In My.Computer.FileSystem.GetFiles(mypath)
        If IsNumeric(Path.GetFileNameWithoutExtension(Ver)) Then
            Versions.Add(Decimal.Parse(Path.GetFileNameWithoutExtension(Ver)).ToString("#0.00")) 
        End If
    Next

    Dim mesg As String = ""
    For Each str As String In Versions
        mesg = mesg & str & vbCrLf
    Next
    MsgBox(mesg)

    Return Versions
    End Function

我对IComparer不是很熟悉,但如果需要我可以实现它

示例中的class将版本号存储为编码的Long,每个位置在0到255之间,8位。除非你有很多这样的东西,否则可能有点矫枉过正......;)

需要一个带有按钮的表单,

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        'Test of Class VersionNumber
        Dim l As New List(Of VersionNumber)

        Dim test As XElement = <t>
                                   <t>1.11</t>
                                   <t>1</t>
                                   <t>1.2</t>
                                   <t>1.2.3</t>
                                   <t>1.2.3.4</t>
                                   <t>1.1.3</t>
                                   <t>1.1.2</t>
                                   <t>1.10</t>
                                   <t>1.2.1</t>
                                   <t>1.2</t>
                                   <t>1.9</t>
                                   <t>1.2.3.4.5.6.7.8</t>
                               </t>

        Debug.WriteLine("")
        Debug.WriteLine("")
        Dim foo As VersionNumber
        For Each el As XElement In test.Elements
            Debug.WriteLine(el.Value)
            foo = New VersionNumber(el.Value)
            l.Add(foo)
        Next
        l.Sort()

        Debug.WriteLine("")
        Debug.WriteLine("Sorted")
        For Each vn As VersionNumber In l
            Debug.WriteLine(vn.ToString)
        Next
    End Sub
End Class

Public Class VersionNumber
    Implements IComparable(Of VersionNumber), IEquatable(Of VersionNumber)

    Protected Friend _version As Long = 0L
    Private _verstring As String

    Public Sub New(Version As String)
        Dim prts() As String = Version.Trim.Split("."c)
        If prts.Length <= 0 OrElse prts.Length > 8 Then
            Throw New ArgumentException("Invalid version")
        Else
            Dim idx As Integer = 0
            Dim shft As Integer = 8 - (8 - (8 - prts.Length))
            Do While shft < 8
                Dim L As Long = 0L
                If Long.TryParse(prts(idx), L) AndAlso L >= 0 AndAlso L < 256L Then
                    shft += 1
                    idx += 1
                    Me._version = Me._version Or L
                    If shft <> 8 Then Me._version = Me._version << 8
                Else
                    Throw New ArgumentException("Invalid version")
                End If
            Loop
            Me._verstring = Version.Trim
            shft = (8 - (8 - (8 - prts.Length))) * 8
            Me._version = Me._version << shft
        End If
    End Sub

    Public Overrides Function ToString() As String
        Return Me._verstring
    End Function

#Region " and Ops"
    Public Function CompareTo(other As VersionNumber) As Integer _
                Implements IComparable(Of VersionNumber).CompareTo
        'https://msdn.microsoft.com/en-us/library/system.icomparable.compareto(v=vs.110).aspx
        'return values and their meaning:
        ' Less than zero      This instance precedes other in the sort order. 
        ' Zero                This instance occurs in the same position in the sort order as other. 
        ' Greater than zero   This instance follows other in the sort order. 

        If other Is Nothing Then
            Return 1 'By definition, any object compares greater than (or follows) null, and two null references compare equal to each other
        ElseIf Me = other Then
            Return 0
        ElseIf Me < other Then
            Return -1
        Else
            Return 1
        End If
    End Function

    Public Overloads Function Equals(other As VersionNumber) As Boolean _
                Implements IEquatable(Of VersionNumber).Equals

        Select Case Me.CompareTo(other)
            Case 0
                Return True
            Case Else
                Return False
        End Select
    End Function

    Public Shared Operator =(VersNum1 As VersionNumber,
                             VersNum2 As VersionNumber) As Boolean
        Return VersNum1._version.Equals(VersNum2._version)
    End Operator

    Public Shared Operator <>(VersNum1 As VersionNumber, VersNum2 As VersionNumber) As Boolean
        Return Not VersNum1._version.Equals(VersNum2._version)
    End Operator

    Public Shared Operator >(VersNum1 As VersionNumber, VersNum2 As VersionNumber) As Boolean
        Return VersNum1._version > VersNum2._version
    End Operator

    Public Shared Operator <(VersNum1 As VersionNumber, VersNum2 As VersionNumber) As Boolean
        Return VersNum1._version < VersNum2._version
    End Operator

    Public Shared Operator >=(VersNum1 As VersionNumber, VersNum2 As VersionNumber) As Boolean
        Return VersNum1 > VersNum2 OrElse VersNum1.Equals(VersNum2)
    End Operator

    Public Shared Operator <=(VersNum1 As VersionNumber, VersNum2 As VersionNumber) As Boolean
        Return VersNum1 < VersNum2 OrElse VersNum1.Equals(VersNum2)
    End Operator
#End Region

End Class