2011-01-11 12 views

Respuesta

24

se podría hacer algo como esto:

IEnumerable<Person> persons = .. 

var firstPersonAfterJack = persons.SkipWhile(p => p.Name != "Jack") 
            .ElementAt(1); //Zero-indexed, means second 

La idea es producir una secuencia que resulta en elementos de saltar hasta que cumpla con la condición, a continuación, tomar el segundo elemento de que secuencia.

Si no hay garantía de que la consulta devolverá un resultado (por ejemplo, un partido no se encuentra, o es el último elemento de la secuencia), podría reemplazar ElementAt con ElementAtOrDefault, y luego hacer un null-test para comprobar si hay exito fracaso.

Noté que dices en tu pregunta que tienes un ordenado lista de personas. Si pudiera explicar lo que eso significa en mayor detalle, podríamos ofrecer una mejor respuesta (por ejemplo, puede que no tengamos que buscar linealmente la secuencia).

+0

Acaba de vencerme a mí :-) – finnw

+0

@finnw: Incluso elegimos el mismo nombre de propiedad. Imagina si hubiéramos elegido el mismo nombre de persona también. :) – Ani

+0

Esta es una gran solución para una consulta genérica de Linq to Object, pero el operador de consulta 'SkipWhile' no es compatible en Linq con Sql. –

3

SkipWhile es un método que toma un predicado y omite todo hasta que el predicado sea falso. Devuelve ese elemento y todo después.

var remainingPeople = collectionOfPeople.SkipWhile(p => !isThePerson(p)); 
if (remainingPeople.Count() == 1) 
{ 
    // the person was the last in the list. 
} 
var nextPerson = remainingPeople.Skip(1).First(); 

donde isThePerson es un método que toma una persona y devuelve verdadero si es la persona a la que le está interesado.

+0

Hay 2 problemas aquí: 1) Hay una enumeración redundante de la secuencia fuente * completa *. 2) Fallará cuando 'remainingPeople.Count() == 0', es decir, la condición nunca se cumple. – Ani

+0

1) No veo dónde enumera toda la secuencia dos veces. ¿Puedes señalar dónde? 2) Fallará si no está en la lista pero los requisitos dicen que la persona está garantizada en la lista, por lo que no es un problema. –

+1

Recuerde que la mayoría de los operadores LINQ usan ejecución diferida. 'remainingPeople' es una * consulta *, no una lista o matriz. Sus resultados se recuperan dos veces, una para 'Count()' y una para 'Skip (1) .First()'. – Ani

Cuestiones relacionadas