Pregunta

¿Cómo puedo determinar si estoy en el último bucle de un For Each en VB.NET?

¿Fue útil?

Solución

El general, colecciones en el que se pueden realizar en For Each implementar el IEnumerator interfaz. Esta interfaz tiene sólo dos métodos, MoveNext y Reset y una propiedad, Current.

Básicamente, cuando se utiliza un For Each en una colección, se llama a la función MoveNext y lee el valor devuelto. Si el valor devuelto es True, esto significa que hay un elemento válido en el elemento de recogida y se devuelve a través de la propiedad Current. Si no hay más elementos de la colección, la función MoveNext rendimientos False y la iteración se sale.

A partir de la explicación anterior, es claro que el For Each no hace un seguimiento de la posición actual de la colección y así la respuesta a su pregunta es un corto No .

Sin embargo, si usted todavía desea saber si se encuentra en el último elemento de la colección, se puede tratar el siguiente código. Se comprueba (usando LINQ) si el elemento actual es el último elemento.

For Each item in Collection
    If item Is Collection.Last Then
        'do something with your last item'
    End If
Next

Otros consejos

Probablemente sería más fácil de usar simplemente un bucle en lugar de ParaCada. Pero, del mismo modo, se puede mantener un contador dentro de su bucle foreach y ver si su igual a yourCollection.Count - 1, entonces usted está en la última iteración.

Con un foreach, no se puede saber esto hasta que es demasiado tarde (es decir. Que está fuera del circuito).

Tenga en cuenta, que estoy asumiendo que usted está usando algo en el que sólo tiene una interfaz IEnumerable. Si usted tiene una lista, matriz, etc. siga las otras respuestas aquí que utiliza .Count o similares para averiguar cuántos elementos hay, y por lo tanto puede realizar un seguimiento de dónde se encuentra en la colección.

Sin embargo, con sólo IEnumerable / IEnumerator, no hay manera de saber con certeza tiempo o no hay más, si se utiliza foreach.

Si necesita saber esto, utilizar IEnumerable a sí mismo, que es lo que hace foreach.

La solución a continuación es para C #, pero debería traducirse fácilmente a VB.NET:

List<Int32> nums = new List<Int32>();
nums.Add(1);
nums.Add(2);
nums.Add(3);

IEnumerator<Int32> enumerator = nums.GetEnumerator();
if (enumerator.MoveNext())
{
    // at least one value available
    while (true)
    {
        // make a copy of it
        Int32 current = enumerator.Current;

        // determine if it was the last value
        // if not, enumerator.Current is now the next value
        if (enumerator.MoveNext())
        {
            Console.Out.WriteLine("not last: " + current);
        }
        else
        {
            Console.Out.WriteLine("last: " + current);
            break;
        }
    }
}
enumerator.Dispose();

Esta impresión voluntad:

not last: 1
not last: 2
last: 3

El truco es tomar una copia del valor actual, a continuación, pedir al empadronador trate de pasar a la siguiente. Si esto falla, la copia que hizo fue de hecho el último valor, de lo contrario hay más.

Respuesta corta: no puede

Respuesta larga: No hay nada en la semántica de una para cada instrucción que le permite identificar si se está ejecutando la primera, la última o cualquier iteración particular.

Para Cada una está construida en el IEnumerable y IEnumerable <> interfaces y el comportamiento depende de la aplicación que está llamando. Es válido, aunque confuso, de la colección que está iterando para devolver los elementos en un orden diferente cada vez. Afortunadamente, List <> no hace esto.

Si realmente necesita saber que una iteración particular es el último, se podía identificar el último elemento (por adelantado) y luego tomar acción diferente cuando se encuentra con ese elemento.

Más fácil sería para detectar la primero iteración (por ejemplo, a través de un booleano) y luego hacer algo diferente.

Un ejemplo (C #, pero la VB serán similares):

StringBuilder result = new StringBuilder();
bool firstTime = true;
foreach(string s in names)
{
    if (!firstTime)
    {
        result.Append(", ");
    }

    result.Append(s);
    firstTime = false;
}

Comprobar si el elemento es el último elemento del contenedor.

¿Por qué quieres hacer eso?
Se podía colocar las instrucciones después del bucle. (Que se ejecuta en el último elemento)

Sería más fácil de utilizar un bucle en lugar de un ParaCada, sin embargo, puede hacer algo como

If item.Equals(itemCollection(itemCollection.Count)) Then
    ...
End If

interior de su bucle foreach ... Suponiendo que el objeto ha anulado correctamente el método Equals.

Este es probablemente mucho más recursos que simplemente utilizando un bucle o no perder de vista el índice actual en una variable independiente.

No estoy seguro si esto es la sintaxis correcta, que ha sido un largo tiempo desde que he usado VB.

El uso de un estándar "para cada" bucle no se puede. La intención de un "para cada" bucle es permitir al usuario concentrarse en los datos en lugar de la colección subyacente.

sigo volviendo a este post, así que decidió sentarse y pensar sobre este tema y se me ocurrió esto:

    For Each obj In myCollection
        Console.WriteLine("current object: {0}", obj.ToString)

        If Object.ReferenceEquals(obj, myCollection.Last()) Then
            Console.WriteLine("current object is the last object")
        End If
    Next

Se podría incluso reducir la declaración If...Then...End If a una sola línea si se quería. No estoy seguro de si llama .Last() en cada iteración tiene un gran impacto en el rendimiento, pero siempre se puede asignar a una variable de fuera del bucle, si eso es lo que te mantiene despierto por la noche.

este ejemplo de código podría ayudar

For Each item in Collection
  If ReferenceEquals(Collection.Item(Collection.Count - 1), item) Then
    'do something with your last item'
  End If
Next

Si está atado a IEnumerable. ¿Tiene que estar dentro del bucle foreach? Si no se podía declarar una variable justo antes del bucle foreach. Establecer que durante el bucle. A continuación, utilizarlo después del bucle (si no es nulo)

Bueno, hay pocos solución Supongamos que usted está trabajando con CheckBoxList

A continuación, este ejemplo de código podría ayudar:

Dim count As Integer = 0
Dim totalListCount As Integer = CheckBoxList.Items.Count()
For Each li In CheckBoxList.Items
         count += 1
           // This is the Last Item
      If count = totalListCount THEN
          // DO Somthing.....
      END IF
NEXT     

aquí es una cosa simple que no sé si es políticamente correcto, pero funciona

for each item in listOfThings
   if(item = listOfThings.last)then 
       'you found the last loop
   end if
next 
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top