2011-06-21 14 views
57

Estoy pensando en implementar IEnumerable para mi colección personalizada (un árbol) así puedo usar foreach para recorrer mi árbol. Sin embargo, por lo que sé foreach siempre comienza desde el primer elemento de la colección. Me gustaría elegir de qué elemento comienza foreach. ¿Es posible cambiar de alguna manera el elemento desde el que comienza foreach?¿Es posible comenzar a iterar desde un elemento que no sea el primero utilizando foreach?

+0

Seguiría el principio de menos asombro: http://en.wikipedia.org/wiki/Principle_of_least_astonishment – ChaosPandion

+0

Si no comienza desde el primer elemento, ¿cómo define el comportamiento del iterador? ¿Qué pasa cuando llega al final de la secuencia? ¿Luego regresa al primer elemento e itera sobre los elementos restantes? –

+0

El comentario de @ ChaosPandion es a dónde iba con esas preguntas. :) –

Respuesta

101

Sí. Hacer lo siguiente:

Collection<string> myCollection = new Collection<string>; 

foreach (string curString in myCollection.Skip(3)) 
    //Dostuff 

Skip es una función IEnumerable que salta sin embargo muchos se especifica a partir del índice actual. Por otro lado, si desea utilizar solamente los tres primeros se usaría .Take:

foreach (string curString in myCollection.Take(3)) 

Estos incluso pueden ser emparejados juntos, así que si sólo quería los 4-6 artículos que podría hacer:

foreach (string curString in myCollection.Skip(3).Take(3)) 
+2

Tenga en cuenta que C# distingue entre mayúsculas y minúsculas, por lo que ninguno de ellos funcionará como se muestra ... –

+0

Buena llamada. WTB autocompletar (gahh no puede recordar el nombre real) en stackoverflow;) – MoarCodePlz

+0

¿Esto realmente se saltea o simplemente crea una copia? ES DECIR.serían estos dos diferentes: 'foreach (Lista fila en rows.skip (1)) { fila [0] =" newInfo "; } ' vs ' for (int i = 1; i row = rows [i]; fila [0] = "newStuff"; } ' – TigerBear

4

Puede usar Enumerable.Skip para omitir algunos elementos y hacer que comiencen allí.

Por ejemplo:

foreach(item in theTree.Skip(9)) // Skips the first 9 items 
{ 
    // Do something 

Sin embargo, si usted está escribiendo un árbol, es posible que desee proporcionar un elemento en el elemento del árbol en sí que devolverá un nuevo IEnumerable<T> que enumerar desde allí hacia abajo. Esto, potencialmente, sería más útil a largo plazo.

+0

Algo como' IEnumerable SubTree (rootIndex) '? ¡Buena llamada! –

+0

Gracias por responder, saltar parece prometedor, leer información de MSDN sobre omisión Llegué a la conclusión de que tal vez es posible escribir un método StartFrom (este árbol IEnumerable , elemento MyTreeElement) que sería un método de extensión para IEnumerable que devolvería IEnumerable desde el cual debería comenzar a iterar. Entonces quizás podría usar este método como foreach (elemento var en tree.StartFrom (someElement))). – inferno

+0

@inferno: Sí, podría hacerlo fácilmente. Sin embargo, solo agregaría un método/propiedad a MyTreeElement que fuera más parecido a: 'IEnumerable Children', por lo que podría hacer:' foreach (elemento var en someElement.Children) '- mucho más claro que usar métodos de extensión IMO. –

15

Es más fácil utilizar el método Skip en LINQ a Objetos para esto, para saltar un número determinado de elementos:

foreach (var value in sequence.Skip(1)) // Skips just one value 
{ 
    ... 
} 

Obviamente sólo cambia 1 para cualquier otro valor para saltar un número diferente de elementos ..

De forma similar, puede usar Take para limitar el número de elementos que se devuelven.

Puede leer más sobre estos (y los métodos relacionados SkipWhile y TakeWhile) en my Edulinq blog series.

+0

Jon, ¿esto no corre el riesgo de una excepción si "secuencia" es nula? – WEFX

+0

@WEFX: Bueno, no tenemos idea de si 'sequence' puede ser legítimamente' null' o no. Presumiblemente, los OP pueden manejarlo ellos mismos, no es realmente parte de la cuestión ... –

-1

Foreach iterará sobre su colección en la forma definida por su implementación de IEnumerable. Entonces, aunque puede omitir elementos (como se sugirió anteriormente), aún está iterando técnicamente sobre los elementos en el mismo orden.

No estoy seguro de lo que está tratando de lograr, pero su clase podría tener múltiples propiedades IEnumerable, cada una de las cuales enumera los elementos en un orden específico.

Cuestiones relacionadas