Malcolm Hutcheon Malcolm Hutcheon - 29 days ago 8
Vb.net Question

Creating and sorting an array/arraylist/list in vb.net

Currently, I have a List(of String) which contains data similar to:

"207.5,1"
"373,2"
"278.5,3"
"134,4"
"277,5"
"674,7"
"58.5,9"


To this list, I apply the two commands 'list.Sort' then 'list.Reverse' which both do exactly as expected, my List then contains:

"674,7"
"58.5,9"
"373,2"
"278.5,3"
"277,5"
"207.5,1"
"134,4"


As you can see, for all intents and purposes, this has worked perfectly, BUT, the sharp-eyed will notice that the entry "58.5,9" is out of place and should be at the bottom of the list.

I appreciate I am sorting strings here, so I'm bound to fail. What I need to discover please, is how can I copy the contents of the strings per line into another sortable container, which stores my numbers and 'indexes' as integers and/or singles? Ideally, I'll end up with an array or whatever of data like this:

674.0,7
373.0,2
278.5,3
277.0,5
207.5,1
134.0,4
58.5,9


I have tried as many iterations as I can think of (fairly new to this so probably missing the very obvious!). Please help if you can! Thanks.

Answer

If you're going to be using the data more than once then it makes sense to have a class which represents it. That way you can give the parts meaningful names, have an easy way to create a new item, easily manipulate the data, and have your own way of converting it to a string.

It may look like a load of fiddly code, but you only have to write it once and then your life is much simpler when you want to use the data:

Option Infer On
Option Strict On

Module Module1

    Public Class Datum
        Property Number As Decimal
        Property Index As Integer

        Sub New()
            ' default constructor
        End Sub

        Sub New(NumberIndex As String)
            Dim parts = NumberIndex.Split(","c)
            ' a simple parameter check
            If parts.Length <> 2 Then
                Throw New ArgumentException("No comma found in " & NameOf(NumberIndex))
            End If

            Number = CDec(parts(0))
            Index = CInt(parts(1))

        End Sub

        Public Overrides Function ToString() As String
            Return $"{Number},{Index}"

        End Function

    End Class

    Sub Main()
        Dim myList As New List(Of String) From {"207.5,1", "373,2", "278.5,3", "134,4", "277,5", "674,7", "58.5,9"}
        Dim myData = (myList.Select(Function(d) New Datum(d))).ToList()

        Dim dataDescending = myData.OrderByDescending(Function(d) d.Number).ToList()

        Console.WriteLine(String.Join(vbCrLf, dataDescending))

        Console.ReadLine()

    End Sub

End Module

Outputs:

674,7
373,2
278.5,3
277,5
207.5,1
134,4
58.5,9