2012-02-15 30 views
10

Tôi có ứng dụng web MVC3 C# .Net. Tôi có mảng chuỗi bên dưới.LINQ indexOf một mục nhập cụ thể

public static string[] HeaderNamesWbs = new[] 
             { 
              WBS_NUMBER, 
              BOE_TITLE, 
              SOW_DESCRIPTION, 
              HARRIS_WIN_THEME, 
              COST_BOGEY 
             }; 

Tôi muốn tìm chỉ mục của mục nhập nhất định khi ở vòng lặp khác. Tôi nghĩ rằng danh sách sẽ có một IndexOf. Tôi không thể tìm thấy nó. Bất kỳ ý tưởng?

+0

LINQ hoạt động trên các bộ sưu tập không có toán tử chỉ mục. Không có 'IndexOf' – cadrell0

+1

@ cadrell0: Bạn có thể xây dựng một cách dễ dàng - xem câu trả lời của tôi. Có nhiều toán tử LINQ khác nhau cung cấp chỉ mục. –

Trả lời

35

Vâng, bạn có thể sử dụng Array.IndexOf:

int index = Array.IndexOf(HeaderNamesWbs, someValue); 

Hoặc chỉ cần khai báo HeaderNamesWbs thay vào đó, thay vào đó là IList<string> - vẫn có thể là một mảng nếu bạn muốn:

public static IList<string> HeaderNamesWbs = new[] { ... }; 

Lưu ý rằng tôi không khuyến khích bạn để lộ một mảng như public static, thậm chí public static readonly. Bạn nên cân nhắc ReadOnlyCollection:

public static readonly ReadOnlyCollection<string> HeaderNamesWbs = 
    new List<string> { ... }.AsReadOnly(); 

Nếu bạn đã bao giờ muốn điều này cho IEnumerable<T>, bạn có thể sử dụng:

var indexOf = collection.Select((value, index) => new { value, index }) 
         .Where(pair => pair.value == targetValue) 
         .Select(pair => pair.index + 1) 
         .FirstOrDefault() - 1; 

(+1 và -1 là để nó sẽ trở về -1 cho "mất tích" thay vì 0.)

+0

@Jon ... cảm ơn! Đồ tốt. Tôi thích ý tưởng ReadOnlyCollection ... đánh giá cao nó – MikeTWebb

+0

@ jon-skeet Nó sẽ không có ý nghĩa hơn để làm cho mặc định '-1'? 'collection.Select ((giá trị, chỉ mục) => new {value, index}) .Đâu (pair => pair.value == targetValue) .Select (pair => pair.index) .irstOrDefault (-1);' –

+0

@lund.mikkel: Không có quá tải của 'FirstOrDefault' mà có một giá trị mặc định để cung cấp (không giống như' DefaultIfEmpty' ví dụ). –

4

Ngay List có IndexOf(), chỉ cần khai báo nó như ILIst<string> hơn string[]

public static IList<string> HeaderNamesWbs = new List<string> 
            { 
             WBS_NUMBER, 
             BOE_TITLE, 
             SOW_DESCRIPTION, 
             HARRIS_WIN_THEME, 
             COST_BOGEY 
            }; 

int index = HeaderNamesWbs.IndexOf(WBS_NUMBER); 

MSDN: List(Of T).IndexOf Method (T)

8

Tôi đến cuối chuỗi ở đây. Nhưng tôi muốn chia sẻ giải pháp của mình cho vấn đề này. Jon là tuyệt vời, nhưng tôi thích lambdas đơn giản cho tất cả mọi thứ.

Bạn có thể mở rộng LINQ để có được những gì bạn muốn. Nó khá đơn giản để làm. Điều này sẽ cho phép bạn sử dụng cú pháp như:

// Gets the index of the customer with the Id of 16. 
var index = Customers.IndexOf(cust => cust.Id == 16); 

Đây có thể không phải là một phần của LINQ theo mặc định vì yêu cầu liệt kê. Nó không chỉ là một bộ chọn/vị từ hoãn lại.

Ngoài ra, xin lưu ý rằng điều này chỉ trả lại chỉ mục đầu tiên. Nếu bạn muốn chỉ mục (số nhiều), bạn nên trả lại một số IEnumerable<int>yeild return index bên trong phương thức. Và tất nhiên không trở lại -1. Điều đó sẽ hữu ích khi bạn không lọc bằng khóa chính.

public static int IndexOf<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { 

    var index = 0; 
    foreach (var item in source) { 
     if (predicate.Invoke(item)) { 
      return index; 
     } 
     index++; 
    } 

    return -1; 
    } 
Các vấn đề liên quan