2013-08-27 4 views
6

Ich möchte in der Lage sein, eine LINQ-Abfrage auf eine BindingList (Of T), die die Indizes, wo ein Listenobjekt Mitglied ist gleich einem bestimmten Wert.Get Index der übereinstimmenden Wert in Liste mit LINQ

sagen, dass ich eine Liste von einfachen Objekten der Klasse Widget haben:

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

ich die Liste in der Lage sein möchten, dass soetwas wie die unten abfragen:

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

Derart, dass Index enthält den Index des ersten listItem wo widgetList.Item (index) .foo = 5. Was ist der beste Weg, dies zu tun? (Oder soll ich auch LINQ verwenden)

Ich habe mehr C# Methoden gesehen dies nicht in ausreichendem Maße aber ich bin zu tun au fait mit C# zu verstehen, wie sie in VB verwenden

+0

Soweit linq berücksichtigt wird, sind C# und vb Syntax meist die gleichen. Über Ihre Frage: In Titel fragen Sie nach übereinstimmenden Werten (bedeutet, dass Sie mehr als eine Übereinstimmung erwarten), aber in dem Code, den Sie verwenden. Zuerst, was bedeutet, dass Sie nur den ersten Punkt aus ausgewählten Ergebnissen nehmen. –

+0

Also habe ich - bearbeitet um Plural zu entfernen. Danke – Toby

Antwort

6

Es ist möglich, mit LINQ zu erreichen durch den Einsatz die fließende Syntax, da es eine überladene Version der Erweiterungsmethode Select gibt, mit der Sie den Index der Elemente abrufen können.

Versuchen Sie diesen Ansatz:

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 

Im Select ich das Widget Projizieren wie es ist, mit o und der i Parameter repräsentiert den Index. Als nächstes verwende ich FirstOrDefault mit einem Prädikat, um Foo auszuwerten (Sie hätten Where gefolgt von verwenden können, aber das ist kürzer). Sie sollten FirstOrDefault anstatt nur First verwenden, falls keines der Elemente gefunden wird; FirstOrDefault gibt null zurück, wenn nichts gefunden wird, während First eine Ausnahme auslösen würde. Deshalb ist der nächste Schritt, das Ergebnis zu überprüfen und sicherzustellen, dass es nicht null ist.

1

Ich habe auch eine funktionierende Lösung wie unten gefunden, obwohl ich nicht sicher bin, ob dies besser oder schlechter als die anderen Antworten ist.

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

Das funktioniert, aber Sie haben eine neue Sammlung eingeführt, um Ihre ursprüngliche Sammlung zu vergleichen, die * wahrscheinlich * langsamer funktioniert. Aus Lesbarkeitsgründen ist es klarer, gegen die ursprüngliche Sammlung zu arbeiten. Vom Leistungsstandpunkt aus muss der Code "n" Elemente in dem Bereich erzeugen, um die Abfrage auszuwerten. –

+0

@AhmadMageed, Guter Mann, danke, ich werde zu Ihrer Antwort so wechseln :) – Toby

Verwandte Themen