如何在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不是很熟悉,但如果我需要,我可以实现它

示例中的类将版本号存储为编码的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

最新更新