I have this kind of imput in my arraylist:
1
1.1
1.1.1
1.1.1.1
1.1.2
1.10
1.11
1.2
1.9
And I want to sort it, to get result looks like this:
1
1.1
1.1.1
1.1.1.1
1.1.2
1.2
1.9
1.10
1.11
I have found possible solutions in other languages but it is difficult for me to understand them. I have this function that reads the file names of a folder without its extension but I don't know how to order them (I tried to treat them as decimals but it didn't work).
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
I am not very familiar with IComparer but I can implement it if I need it
The class in the example stores the version number as an encoded Long with each position being between 0 and 255, 8 bits. Probably a little overkill unless you have a whole lot of this ... ;)
A form with a button is required,
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