2011-01-17 41 views
7

Duplicar posible:
Foreach loop, determine which is the last iteration of the loopC# ¿cómo obtener la última vez en la declaración de foreach?

foreach (DataRowView row in orderedTable.DefaultView) 
{ 
    if(lasttime) do-something; 
} 

orderedtable es una tabla de datos

¿alguien sabe cómo averiguar si estamos en la última iteración foreach? tenga en cuenta que tengo duplicados en la tabla de pedidos

+0

¿Qué es 'lasttime'? ¿Qué quieres decir con eso? – Oded

+0

la última iteración de foreach –

+0

Hay una buena explicación de por qué esto no se puede hacer aquí: http://stackoverflow.com/questions/43021/c-get-index-of-current-foreach-iteration –

Respuesta

7

La construcción foreach no sabe tal cosa, ya que se aplica por igual a las listas ilimitadas. Simplemente no tiene forma de saber qué es un último elemento.

Se puede recorrer la forma manual, así, sin embargo:

for (int i = 0; i < orderedTable.DefaultView.Count; i++) { 
    DataRowView row = orderedTable.DefaultView[i]; 
    if (i == orderedTable.DefaulView.Count - 1) { 
     // dosomething 
    } 
} 
+0

(cruce los dedos y espere que la propiedad 'Count' exista y no sea lenta ...) – Mehrdad

+0

Bueno, MSDN lo enumera. No busqué si puede ser opcional o no (de hecho, la cosa con métodos opcionales es algo que solo sé de Java hasta ahora). – Joey

2

Deberá usar un bucle for para tener un comportamiento diferente en el último elemento.

for (int i = 0; i < orderedTable.DefaultView.Count; i++) 
{ 
    //do stuff 
    if (i == orderedTable.DefaultView.Count - 1) 
    { 
     //do additional special stuff 
    } 
} 

Vale la pena señalar que "el otro al Plato" tiene una aplicación para un "inteligente numerable", que es compatible con una última propiedad. Vea el artículo aquí: http://msmvps.com/blogs/jon_skeet/archive/2007/07/27/smart-enumerations.aspx

Con esto se podría escribir algo como esto (podría obtener los detalles equivocado, no he probado a mí mismo):

foreach (SmartEnumerable<DataRowView> item in new SmartEnumerable<DataRowView>(orderedTable.DefaultView)) 
{ 
    DataRowView row = item.Value; 
    if(item.IsLast) 
    { 
     ///do special stuff 
    } 
} 
+0

me puede mostrar por favor –

0

Si usted está preocupado en no perder de su iteración, ¿por qué no utilizar un for en su lugar o un foreach? A continuación, puede hacer lo siguiente:

for(int i = 0; i<orderedTable.DefaultView.Count-1;i++) 
{ 
    if(i==orderedTable.DefaultView.Count-1) 
    { 
     // Last Row 
    } 
} 
0

En lugar de utilizar foreach obtener el IEnumerator. Si MoveNext devuelve null, el anterior fue el último.

para que funcione también, por supuesto.

16

El correcta método que funciona en todos los casos es utilizar el IEnumerator<T> directamente:

using (var enumerator = orderedTable.DefaultView.GetEnumerator()) 
{ 
    if (enumerator.MoveNext()) 
    { 
     bool isLast; 
     do 
     { 
      var current = enumerator.Current; 
      isLast = !enumerator.MoveNext(); 
      //Do stuff here 
     } while (!isLast); 
    } 
} 

Este método funciona incluso si su colección no tiene una propiedad Count, e incluso si lo hace , este método será más eficiente si la propiedad Count es lenta.

0

Usted podría hacer algo como lo siguiente:

foreach (DataRowView row in orderedTable.DefaultView) 
{ 
    if(row == orderedTable.DefaultView.Last()) do-something; 
} 

pero es bastante ineficiente.

3

Un enfoque alternativo que no creo que nadie haya publicado. Esto funciona bien si no conoce el conteo con anticipación.

DataRowView lastRow; 
foreach (DataRowView row in orderedTable.DefaultView) 
{ 
    // Do something... 

    lastRow = row; 
} 

if (lastRow != null) 
{ 
    // Do something with last row 
} 
+0

Este método requiere potencialmente la duplicación de código, que todos deseamos evitar ... – Mehrdad

+1

@Lambert: cada fila, incluida la última, ejecuta el bloque de código principal, por lo que no hay duplicación allí. Supongo que de esta manera no funcionaría si * no * quiere '// Hacer algo ...' en la última fila, ya que solo le permite ejecutar código en la última fila * además * de lo que todos los demás filas corre –

0

El código que has publicado es idéntica a:

if (orderedTable.DefaultView.Rows.Count > 0) 
    do-something; 

Si eso no hace lo que quiere, tendrá que explicar lo que hace lastTime.

0

Si entiendo su pregunta, ¿esto ayuda?

int lastrow = 0; 
foreach (DataRow row in table.Rows) // Loop over the rows. 
{ 
    lastrow++; 
    // Do Something 
    if (lastrow == (table.Rows.Count - 1)) 
    { 
     // Do something else 
    } 
} 
+0

sería mejor como un bucle for, porque ya introduce una variable local, pero funciona. – caesay

Cuestiones relacionadas