Home > database >  Linq vb.net simple query returning bad results (no yielding results)
Linq vb.net simple query returning bad results (no yielding results)

Time:10-27

Hello I'm trying to develop a Linq query to find the Lowest Unique Value or else Lowest Value which is also sorted by Row and Column Value. First it does the Lowest Unique Value Exact match using BinarySearch (unique value) If nothing is found then it does a Partial Match (lowest value then lowest row then column) Whichever has the smallest Value is the output (unique (smallest first)) or (not found (smallest second or first if unique not found)).

Console returns this value

2,0,0

When it should be


2,1,1

Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click
    Dim UniqueValuesFound As New List(Of Short)
    Dim ValuesFoundInPath As New List(Of FoundValue)

    UniqueValuesFound.Add(1)
    'UniqueValuesFound.Add(0)
    'UniqueValuesFound.Add(2)
    'UniqueValuesFound.Add(3)

    UniqueValuesFound = UniqueValuesFound.Distinct().ToList()
    UniqueValuesFound.Sort()

    Dim foundValue As New FoundValue
    foundValue.Value = 2
    foundValue.Row = 1
    foundValue.Column = 1
    ValuesFoundInPath.Add(foundValue)

    'foundValue = New FoundValue
    'foundValue.Value = 3
    'foundValue.Row = 0
    'foundValue.Column = 2
    'ValuesFoundInPath.Add(foundValue)

    'foundValue = New FoundValue
    'foundValue.Value = 2
    'foundValue.Row = 0
    'foundValue.Column = 2
    'ValuesFoundInPath.Add(foundValue)

    'foundValue = New FoundValue
    'foundValue.Value = 0
    'foundValue.Row = 2
    'foundValue.Column = 0
    'ValuesFoundInPath.Add(foundValue)


    Dim alreadyFound As Boolean = False

    Dim matching = ValuesFoundInPath.Where(Function(s)
                                               Dim index As Integer = UniqueValuesFound.BinarySearch(s.Value)
                                               If alreadyFound = False AndAlso index >= 0 Then
                                                   alreadyFound = True
                                                   Return True 'UniqueValuesFound(index) 'exact match
                                               ElseIf alreadyFound = False AndAlso index < 0 Then
                                                   alreadyFound = True
                                                   Return True 's.Value
                                               Else
                                                   Return False
                                               End If
                                           End Function).OrderBy(Function(p) p.Value).ThenBy(Function(p) p.Row).ThenBy(Function(p) p.Column)


    Console.WriteLine(matching(0).Value.ToString & "," & matching(0).Row.ToString & "," & matching(0).Column.ToString)


End Sub

CodePudding user response:

Solved it, needed to use Find instead of Where and problem disappeared!.

The answer now reqires 2 linq queries instead of one cannot do chaining on Find

    ValuesFoundInPath = ValuesFoundInPath.OrderBy(Function(p) p.Row).ThenBy(Function(p) p.Column).ThenBy(Function(p) p.Value).ToList()

    Dim alreadyFound As Boolean = False

    Dim matching = ValuesFoundInPath.Find(Function(s)
                                              Dim index As Integer = UniqueValuesFound.BinarySearch(s.Value)
                                              If alreadyFound = False AndAlso index >= 0 Then
                                                  alreadyFound = True
                                                  Return True 'UniqueValuesFound(index) 'exact match
                                              ElseIf alreadyFound = False AndAlso index < 0 Then
                                                  alreadyFound = True
                                                  Return True 's.Value
                                              Else
                                                  Return False
                                              End If
                                          End Function)
    Dim result As New Result
    result.Answer = matching.Value
    result.CurrentRow = matching.Row
    result.CurrentColumn = matching.Column

You may have problems since Find(...) pre-sorts the list of values always. So you need to use FindIndex(...) this avoids the sorting issue.

    Dim matchingIndex = ValuesFoundInPath.FindIndex(Function(s)
                                                        Dim index As Integer = UniqueValuesFound.BinarySearch(s.Value)
                                                        If alreadyFound = False AndAlso index >= 0 Then
                                                            alreadyFound = True
                                                            Return True 'UniqueValuesFound(index) 'exact match
                                                        ElseIf alreadyFound = False AndAlso index < 0 Then
                                                            alreadyFound = True
                                                            Return True 's.Value
                                                        End If
                                                        Return False 'No match.
                                                    End Function)

    If matchingIndex < 0 Then MessageBox.Show("Wtf!")

    Dim result As New Result
    result.Answer = ValuesFoundInPath(matchingIndex).Value
    result.CurrentRow = ValuesFoundInPath(matchingIndex).Row
    result.CurrentColumn = ValuesFoundInPath(matchingIndex).Column

It makes the OrderBy(...) useless because Find(...) pre-sorts the lists by incrementing values.

  • Related