Home > Blockchain >  VB.net, Linq -- How to compare items in List of Strings
VB.net, Linq -- How to compare items in List of Strings

Time:12-08

I have got a list of Strings looking like this:

List of Strings

The items of the list of Strings are formated like this "#,@" where # stands for an integer number and @ stands for a string or number.

I need to find the index of the first occurrence where the integer number is lower than the integer number of the previous item.

I am able to find it using a loop over all entries like this:

  For X = 0 To UBound(TempList.ToArray) - 1
      If Val(Left(TempList(X), InStr(TempList(X), ",") - 1)) > Val(Left(TempList(X   1), InStr(TempList(X   1), ",") - 1)) Then
        Dim Result As String = TempList(X) & " -- " & TempList(X   1)
      End If
    Next

Loop solution

I am sure that this can be done much smarter using linq - but my very poor knowledge regarding linq is not enough ...

Can someone please give me a hint?

CodePudding user response:

Linq is cool but it is not necessarily faster. It is looping internally.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim TempList As New List(Of String) From {"450,245.5", "510,1", "520,1", "703,1", "704,0", "705,0", "706,0", "901,1.244", "921,3", "1,1", "2,1", "3,0"}

    Dim Result As String = ""
    For i As Integer = 1 To TempList.Count - 1
        If CInt(TempList(i).Split(","c)(0)) < CInt(TempList(i - 1).Split(","c)(0)) Then
            Result = $"{TempList(i)} At index {i} -- {TempList(i - 1)}"
            Exit For 'Stop looping when found
        End If
    Next
    MessageBox.Show(Result)
End Sub

CodePudding user response:

You can use LINQ for the loop, but I do think a For / For Each is sufficient - see Mary's answer.

But at least, you could use LINQ to parse your list into something other than strings to make it more manageable when it's used. This will decouple your code a bit and will make it clearer. I'll hold the pair of data in a Tuple(Of Double, String). If I knew the first item was distinct, I would use a Dictionary(Of Double, String).

So for fun, you can use TakeWhile instead of a For / For Each.

Dim TempList = { "450,245.5", "510,1", "520,1", "701,0", "702,0", "703,1", "704,0", "705,0", "706,0", "720,0", "901.2,455", "921,3", "1,1", "2,1", "3,0"}

Dim parsedList = TempList.
    Select(Function(s) s.Split(","c)).
    Select(Function(ss) (CDbl(ss(0)), ss(1)))

Dim lastValue As Double = Double.NaN

Dim index = parsedList.TakeWhile(
    Function(t)
        Dim result = Double.IsNaN(lastValue) OrElse t.Item1 > lastValue
        lastValue = t.Item1
        Return result
    End Function).Count()

Dim item = parsedList(index)

Console.WriteLine($"Index: {index}, number: {item.Item1}, string: {item.Item2}")

Index: 12, number: 1, string: 1

This is basically just making a For Each with LINQ. It's probably not necessary, and a simple loop is arguably more readable, and you won't gain any benefit in performance either.

  • Related