Linq 最低唯一值或最低行和列值以完全匹配或部分匹配中的较小者为准

Linq Lowest Unique Value or Lowest Row and Column Value Whichever Exact match or Partial Match Whichever is Value is smaller

您好,我正在尝试开发一个 Linq 查询来查找最低唯一值或最低值也按行和列值排序。
首先,它执行最低唯一值完全匹配(唯一值)
如果未找到任何内容,则它会进行部分匹配(最低值然后是最低行然后是列)
以具有最小值的为输出(唯一或未找到)。

Table 数据

Row Column Value
1 1 2
0 2 3
0 2 2

输出应该是 table 0,2,2 中的最后一个数据,因为它具有最低行并且是重复值(第 1 行和第 0 行)。

如果您添加数据 2,0,0(值为 0)将否决重复值 (2's)。

Row Column Value
1 1 2
0 2 3
0 2 2
2 0 0

   Structure FoundValue
        Dim Value As Short
        Dim Row As Integer
        Dim Column As Integer
    End Structure
  
   Dim UniqueValuesFound As New List(Of Short)
   Dim ValuesFoundInPath As New List(Of FoundValue)

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

   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)

'New Attempt
    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)
    'New Attempt
        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)

看看 'New Attempt 代码本身,我想做的是找到第一个在 UniqueValuesFound 中完全匹配的值,如果找不到 UniqueValuesFound 数组然后默认吐出它可以找到的部分匹配最低值。数组 ValuesFoundInPath 包含随机顺序的所有值以及 Column 和 Row 类型,必须对它们进行排序以进行部分匹配以首先找到最低的 Row。

我终于解决了!需要使用 Find 而不是 Where,问题就消失了!

答案现在需要 2 个 linq 查询,而不是一个不能在 Find

上进行链接的查询
    ValuesFoundInPath = ValuesFoundInPath.OrderBy(Function(p) p.Value).ThenBy(Function(p) p.Row).ThenBy(Function(p) p.Column).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

您可能会遇到问题,因为 Find(...) 总是对值列表进行预排序。所以你需要使用 FindIndex(...) 这避免了排序问题。

    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

它使 OrderBy(...) 无用,因为 Find(...) 通过递增值对列表进行预排序。