【问题标题】:Get index of matching value in List using LINQ使用 LINQ 获取列表中匹配值的索引
【发布时间】:2013-08-27 14:40:00
【问题描述】:

我希望能够在 BindingList(Of T) 上运行 LINQ 查询,该查询返回列表对象成员等于特定值的 索引

假设我有一个简单的类小部件对象列表:

Public Class widget
    Public Property foo As Integer
    Public Property bar As String
End Class
Dim widgetList As BindingList(Of widget)

我希望能够像下面这样查询列表:

Dim test As Integer = 5
Dim index = (From i In widgetList
             Where i.foo = test
             Select i.index).First

这样的索引包含第一个 listItem 的索引,其中 widgetList.Item(index).foo = 5。最好的方法是什么? (或者我什至应该使用 LINQ)

我已经看到了几种 C# 方法来做到这一点,但我对 C# 不够熟悉,无法理解如何在 VB 中使用它们

【问题讨论】:

  • 就 linq 的考虑而言,c# 和 vb 的语法基本相同。关于您的问题:在标题中您询问的是匹配值(意味着您期望更多的匹配项),但在您使用的代码中 .First,这意味着您只从选定的结果中获取第一项。
  • 所以我做了 - 编辑删除复数。谢谢

标签: .net vb.net linq


【解决方案1】:

可以使用流畅的语法通过 LINQ 实现,因为有一个重载版本的 Select 扩展方法可以让您获取项目的索引。

试试这个方法:

Dim test As Integer = 5
Dim query = widgetList.Select(Function(o,i) New With { .Widget = o, .Index = i}) _
                      .FirstOrDefault(Function(item) item.Widget.Foo = test)
If query Is Nothing
    Console.WriteLine("Item not found")
Else
    Console.WriteLine("Item found at index {0}", query.Index)
End If

Select 中,我使用o 按原样投影Widget,i 参数代表索引。接下来我使用FirstOrDefault 和一个谓词来评估Foo(您可以使用Where 后跟FirstOrDefault,但这更短)。如果没有找到任何项目,您应该使用FirstOrDefault 而不仅仅是First;如果没有找到,FirstOrDefault 会返回 null,而First 会抛出异常。这就是为什么下一步是检查结果并确保它不为空。

【讨论】:

    【解决方案2】:

    我还找到了如下的可行解决方案,但我不确定这是否比其他答案更好或更差。

    Dim index = Enumerable.Range(0, widgetList.Count) _
                .Where(Function(i) widgetList.Item(i).foo = test) _
                .First
    

    【讨论】:

    • 这可行,但您引入了一个新集合来与您的原始集合进行比较,可能执行较慢。从可读性的角度来看,针对原始集合工作会更清晰。从性能的角度来看,代码必须在范围内生成n 项来评估查询。
    • @AhmadMageed,好人,谢谢,我会改用你的答案 :)
    猜你喜欢
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 1970-01-01
    • 2021-11-13
    • 2011-11-22
    相关资源
    最近更新 更多