2012-02-15 92 views
10

我有一個MVC3 C#.Net網絡應用程序。我有下面的字符串數組。LINQ indexOf特定條目

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

我想在另一個循環中找到給定條目的索引。我認爲這份名單會有一個IndexOf。我找不到它。有任何想法嗎?

+0

LINQ對沒有索引運算符的集合進行操作。沒有'IndexOf' – cadrell0 2012-02-15 19:49:23

+1

@ cadrell0:你可以很容易地構建一個 - 請參閱我的答案。有各種提供索引的LINQ操作符。 – 2012-02-15 19:53:17

回答

35

那麼你可以使用Array.IndexOf

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

或者只是聲明HeaderNamesWbs作爲一個IList<string>而不是 - 哪個還可以,如果你想要一個數組:

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

注意,我會鼓勵你暴露數組作爲public static,甚至public static readonly。你應該考慮ReadOnlyCollection

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

如果你想這對IEnumerable<T>,你可以使用:

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

(+1和-1是這樣它會返回-1 「失蹤」而不是0.)

+0

@Jon ...謝謝!好東西。我喜歡ReadOnlyCollection想法...讚賞它 – MikeTWebb 2012-02-15 21:22:35

+0

@ jon-skeet使默認的'-1'變得更有意義嗎? (pair => pair.index).FirstOrDefault(-1);'選擇((value,index)=> new {value,index})。 – 2016-02-09 09:40:14

+0

@lund。mikkel:沒有重載'FirstOrDefault',它需要一個默認值來提供(例如,與'DefaultIfEmpty'不同)。 – 2016-02-09 09:43:18

4

List具有的IndexOf(),只是聲明爲ILIst<string>,而不是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

我遲到了。但我想分享我的解決方案。 Jon's很棒,但我更喜歡簡單的lambda表達式。

你可以擴展LINQ本身來得到你想要的。這很容易做到。這將允許你使用如下語法:

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

這可能不是LINQ的一部分,因爲它需要枚舉。這不僅僅是另一個延遲選擇器/謂詞。

此外,請注意,這僅返回第一個索引。如果你想索引(複數),你應該在方法內返回一個IEnumerable<int>yeild return index。當然,不要返回-1。如果您不是通過主鍵進行篩選,那將非常有用。

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; 
    }