Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get index of matching value in List using LINQ

Tags:

.net

vb.net

linq

I would like to be able to run a LINQ query on a BindingList(Of T) that returns the indexes where a list object member is equal to a particular value.

say I have a list of simple objects of class widget:

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

I'd like to be able to query the list some thing like the below:

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

Such that index contains the index of the first listItem where widgetList.Item(index).foo = 5. What is the best way to do this? (Or should I even be using LINQ)

I have seen several C# methods to do this but Im not sufficiently au fait with C# to understand how to use them in VB

like image 664
Toby Avatar asked Aug 27 '13 14:08

Toby


2 Answers

It's possible to achieve with LINQ by using the fluent syntax since there's an overloaded version of the Select extension method that lets you get the index of the items.

Try this approach:

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

In the Select I'm projecting the Widget as is, using o, and the i parameter represents the index. Next I use FirstOrDefault with a predicate to evaluate Foo (you could've used Where followed by FirstOrDefault, but this is shorter). You should use FirstOrDefault instead of just First in case none of the items are found; FirstOrDefault will return null if nothing is found, whereas First would throw an exception. That's why the next step is to check the result and make sure it isn't null.

like image 75
Ahmad Mageed Avatar answered Sep 23 '22 11:09

Ahmad Mageed


I have also found a working solution as below, though I am not sure if this is any better or worse than the other answers.

Dim index = Enumerable.Range(0, widgetList.Count) _
            .Where(Function(i) widgetList.Item(i).foo = test) _
            .First
like image 43
Toby Avatar answered Sep 23 '22 11:09

Toby