2010-11-20 9 views
27

Supongamos que tengo la matriz string[] weekDays = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };, y quiero averiguar el índice de los elementos de la matriz que contienen 's'. ¿Cómo puedo hacer esto usando Linq?¿Cómo seleccionar el índice de matriz después de la cláusula Where usando Linq?

He intentado int[] indexOfDaysContainingS = weekDays.Where(day => day.Contains("s")).Select((day, index) => index).ToArray();, pero esto devuelve 0,1,2 como supuestamente se está consiguiendo el índice de la IEnumberable<string> filtrada después de la cláusula where() en su lugar. Si pongo Select() primero, entonces todo lo que tengo es el índice y no puedo filtrar por los días.

¿Qué debo cambiar para que funcione y devolver 1,2,3 en su lugar?

+0

Yo sé que no es parte de la pregunta, pero ¿por qué no t use hacer esto con un bucle for en lugar de Linq. Usted habría ahorrado muchos minutos de desarrollo. –

Respuesta

34

Usted puede hacerlo de esta manera:

weekDays.Select((day, index) => new { Day = day, Index = index }) 
     .Where(x => x.Day.Contains("s")) 
     .Select(x => x.Index) 
     .ToArray(); 

No estoy seguro si esto es óptima ..

+1

+1. Reformateado para mayor claridad; espero que no te importe – Ani

+0

@Ani - Gracias. Supongo que debería despertarme correctamente antes de ir a SO :) – Patko

+0

@Patko, pero ¿cómo sabía tomar el índice de la matriz y asociarlo con el "índice" que colocaste en la propiedad Index? –

15

respuesta de Patko es el camino a seguir en el caso general.

Aquí hay 2 opciones más:

// Idea only works with collections that can be accessed quickly by index. 
int[] indices = Enumerable.Range(0, weekDays.Length) 
          .Where(index => weekDays[index].Contains("s")) 
          .ToArray(); 

Con MoreLinq:

// Similar to Patko's idea, except using a 'named' type. 
int[] indices = weekDays.AsSmartEnumerable() 
         .Where(item => item.Value.Contains("s")) 
         .Select(item => item.Index) 
         .ToArray(); 
+0

Gracias por las alternativas. ¿Hay alguna razón por la que el rendimiento sea diferente usando tu primera alternativa frente a la respuesta de Patko para una matriz grande? No estoy seguro de cuál es la mejor opción. – mikel

+1

@ miket2e: la respuesta de Patko es la general; el enfoque 'Rango' no funciona bien con secuencias sin lista; entonces es difícil hacer una comparación "justa". Para las matrices, creo * que * el enfoque de 'Rango' sería más rápido: hay * probablemente * menos asignación de montón, es * posiblemente * más compatible con la memoria caché, etc. (fíjense en las palabras de comadreja). Aunque no me creas, ¡mídelo! * Quizás * ni siquiera deberías estar usando LINQ aquí. – Ani

+1

(1 enumerador menos) – Ani

-1

esto debería funcionar:

weekDays.Where(a => a.Contains("s")).Select((a, i) => i).ToArray(); 
+1

Use la herramienta de formato de código y explique su respuesta – NSNoob

+0

No creo que la lógica sea correcta en este ejemplo, ya que el valor del índice devuelto será después de que la colección ya se haya filtrado en lugar del índice relativo al original colección. –

Cuestiones relacionadas