2013-08-27 7 views
6

のインデックスを返すBindingList(Of T)に対してLINQクエリを実行したい場合、リストオブジェクトのメンバが特定の値と等しい場合。 LINQを使用してList内の一致する値のインデックスを取得する

は、私はクラスのウィジェットの簡単なオブジェクトのリストを持っていると言う:

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を使用する必要があります)

私はそれを使用してLINQを実現することが可能ですかVB

+0

linqと見なされる限り、C#とvbの構文はほとんど同じです。あなたの質問について:タイトルでは、valueSと一致するかどうかを尋ねています(これは、一致するものが1つ多いことを意味します)。しかし、使用しているコードでは、最初の項目だけを選択します。 –

+0

だから私は複数を削除するように編集しました。ありがとう – Toby

答えて

6

でそれらを使用するために理解するためにC#でのau faitが十分イムしかし、これをしないでくださいするには、いくつかのC#のメソッドを見てきましたあなたが項目のインデックスを得ることができるSelect拡張メソッドのオーバーロードされたバージョンがあるので、流暢な構文。

は、このアプローチを試してみてください: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 

をあるように私はoを使用して、ウィジェットを投影してる、とiパラメータは、インデックスを表します。次に、FirstOrDefaultという述語を使用してFooを評価します(Whereに続いてFirstOrDefaultを使用した可能性がありますが、これは短くなります)。見つからない場合はFirstの代わりにFirstOrDefaultを使用してください。 FirstOrDefaultは何も見つからない場合はnullを返しますが、Firstは例外をスローします。だからこそ次のステップは結果をチェックし、それがヌルでないことを確認することです。

1

私は以下のような解決策を見つけましたが、これが他の回答よりも良いか悪いかわかりません。

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

これはうまくいきますが、元のコレクションと比較するために新しいコレクションを導入しました。おそらく*遅くなります。読みやすさの観点から、元のコレクションに対して作業することは明らかです。パフォーマンスの観点から、コードはクエリを評価するために範囲内に 'n'個のアイテムを生成する必要があります。 –

+0

@AhmadMageed、いい男、ありがとう、私はあなたの答えに切り替えるよ:) – Toby

関連する問題