2013-08-27 32 views
6

Tôi muốn có thể chạy truy vấn LINQ trên BindingList (T) trả về chỉ số trong đó thành viên đối tượng danh sách bằng với một giá trị cụ thể.Nhận chỉ mục giá trị khớp trong Danh sách bằng LINQ

nói rằng tôi có một danh sách các đối tượng đơn giản của phụ tùng lớp:

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

Tôi muốn để có thể truy vấn danh sách một số điều như sau: chỉ số

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

như vậy mà chứa chỉ mục của listItem đầu tiên trong đó widgetList.Item (index) .foo = 5. Cách tốt nhất để làm điều này là gì? (Hoặc nên tôi thậm chí còn được sử dụng LINQ)

Tôi đã thấy một vài phương thức trong C# để làm điều này nhưng Im không đủ au fait với C# để hiểu làm thế nào để sử dụng chúng trong VB

+0

Theo như LINQ được xem xét, cú pháp C# và vb hầu như giống nhau. Về câu hỏi của bạn: trong tiêu đề bạn đang hỏi về giá trị khớp (có nghĩa là bạn đang mong đợi nhiều hơn một giá trị phù hợp) nhưng trong mã bạn đang sử dụng. Đầu tiên, điều đó có nghĩa là bạn chỉ đang lấy mục đầu tiên từ các kết quả đã chọn. –

+0

Vì vậy, tôi đã làm - chỉnh sửa để loại bỏ số nhiều. Cảm ơn – Toby

Trả lời

6

Có thể đạt được với LINQ bằng cách sử dụng cú pháp thông thạo vì có phiên bản quá tải của phương pháp mở rộng Select cho phép bạn lấy chỉ mục của các mục.

Hãy thử phương pháp này:

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 

Trong Select Tôi đang chiếu Widget như là, sử dụng o, và tham số i đại diện cho chỉ số. Tiếp theo, tôi sử dụng FirstOrDefault với biến vị ngữ để đánh giá Foo (bạn có thể đã sử dụng Where theo sau là FirstOrDefault, nhưng điều này ngắn hơn). Bạn nên sử dụng FirstOrDefault thay vì chỉ First trong trường hợp không tìm thấy mục nào; FirstOrDefault sẽ trả về null nếu không tìm thấy gì, trong khi First sẽ ném một ngoại lệ. Đó là lý do tại sao bước tiếp theo là kiểm tra kết quả và chắc chắn rằng nó không phải là null.

1

Tôi cũng đã tìm thấy một giải pháp làm việc như dưới đây, mặc dù tôi không chắc liệu điều này có tốt hơn hay xấu hơn các câu trả lời khác hay không.

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

Điều đó có tác dụng nhưng bạn đã giới thiệu một bộ sưu tập mới để so sánh với bộ sưu tập gốc của bạn, mà * có thể * hoạt động chậm hơn. Từ một quan điểm dễ đọc, nó rõ ràng hơn để làm việc với bộ sưu tập gốc. Từ quan điểm hiệu năng, mã phải tạo các mục 'n' trong phạm vi để đánh giá truy vấn. –

+0

@AhmadMageed, Người đàn ông tốt, cảm ơn, tôi sẽ chuyển sang câu trả lời của bạn để :) – Toby