2012-02-15 32 views
10

Tengo una aplicación web MVC3 C# .Net. Tengo la matriz de cadena a continuación.índice LINQ de una entrada en particular

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

Deseo encontrar el índice de una entrada determinada cuando esté en otro ciclo. Pensé que la lista tendría un IndexOf. No puedo encontrarlo ¿Algunas ideas?

+0

LINQ opera en colecciones que no tienen un operador de índice. No hay 'IndexOf' – cadrell0

+1

@ cadrell0: aunque puedes construir uno fácilmente, mira mi respuesta. Hay varios operadores LINQ que proporcionan el índice. –

Respuesta

35

Bien se puede utilizar Array.IndexOf:

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

O simplemente declarar HeaderNamesWbs como un IList<string> en su lugar, que todavía puede ser un array si quieres:

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

Tenga en cuenta que Yo te desanime de la exposición de una matriz como public static, incluso public static readonly. Debe tener en cuenta ReadOnlyCollection:

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

Si alguna vez quiere esto para IEnumerable<T>, se puede utilizar:

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

(La 1 y -1 son por lo que volverá -1 para "perdido" en lugar de 0.)

+0

@Jon ... ¡gracias! Buen material. Me gusta la idea ReadOnlyCollection ... lo agradezco – MikeTWebb

+0

@ jon-skeet ¿No tendría más sentido hacer el '-1' predeterminado? 'collection.Select ((value, index) => new {value, index}). Where (pair => pair.value == targetValue) .Select (pair => pair.index) .FirstOrDefault (-1);' –

+0

@lund.mikkel: no hay sobrecarga de 'FirstOrDefault' que toma un valor predeterminado para suministrar (a diferencia de' DefaultIfEmpty' por ejemplo). –

4

derecho List tiene IndexOf(), simplemente declara como ILIst<string> en lugar de 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

Llegué tarde al hilo aquí. Pero quería compartir mi solución a esto. Jon es increíble, pero prefiero lambdas simples para todo.

Puede extender LINQ para obtener lo que desea. Es bastante simple de hacer. Esto le permitirá usar sintaxis como:

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

Esto no forma parte de LINQ de forma predeterminada porque requiere enumeración. No es solo otro selector/predicado diferido.

Además, tenga en cuenta que esto solo devuelve el primer índice. Si desea índices (en plural), debe devolver un IEnumerable<int> y yeild return index dentro del método. Y, por supuesto, no devuelva -1. Eso sería útil cuando no está filtrando por una clave principal.

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