Saltar al contenido

¿Cómo encuentras el último bucle en un For Each (VB.NET)?

Hacemos una revisión profunda cada una de las reseñas en nuestra página web con el objetivo de enseñarte en todo momento información con la mayor veracidad y certera.

Solución:

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

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

De la explicación anterior, es claro que el For Each no rastrea la posición actual en la colección y así la respuesta a tu pregunta es corta No.

Sin embargo, si aún desea saber si está en el último elemento de su colección, puede probar el siguiente código. 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

Es importante saber que llamar Last() en una colección enumerará toda la colección. Por lo tanto, no se recomienda llamar Last() en los siguientes tipos de colecciones:

  • Colecciones de transmisión
  • Colecciones computacionalmente costosas
  • Colecciones con alta tendencia a la mutación

Para tales colecciones, es mejor obtener un enumerador para la colección (a través de la GetEnumerator() función) para que pueda realizar un seguimiento de los elementos usted mismo. A continuación se muestra una implementación de muestra a través de un método de extensión que genera el índice del elemento, así como si el elemento actual es el primero o el último elemento de la colección.


Public Iterator Function EnumerateEx(Of T)(collection As IEnumerable(Of T))
    As IEnumerable(Of (value As T, index As Integer, isFirst As Boolean, isLast As Boolean))

    Using e = collection.GetEnumerator()
        Dim index = -1
        Dim toYield As T

        If e.MoveNext() Then
            index += 1
            toYield = e.Current
        End If

        While e.MoveNext()
            Yield (toYield, index, index = 0, False)
            index += 1
            toYield = e.Current
        End While

        Yield (toYield, index, index = 0, True)
    End Using
End Function

Aquí hay un ejemplo de uso:

Sub Main()
    Console.WriteLine("Index   Value   IsFirst   IsLast")
    Console.WriteLine("-----   -----   -------   ------")

    Dim fibonacci = 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89

    For Each i In fibonacci.EnumerateEx()
        Console.WriteLine(String.Join("   ", $"i.index,5",
                                             $"i.value,5",
                                             $"i.isFirst,-7",
                                             $"i.isLast,-6"))
    Next

    Console.ReadLine()
End Sub

Producción

Index   Value   IsFirst   IsLast
-----   -----   -------   ------
    0       0   True      False
    1       1   False     False
    2       1   False     False
    3       2   False     False
    4       3   False     False
    5       5   False     False
    6       8   False     False
    7      13   False     False
    8      21   False     False
    9      34   False     False
   10      55   False     False
   11      89   False     True

Probablemente sería más fácil usar un bucle For en lugar de ForEach. Pero, de manera similar, puede mantener un contador dentro de su bucle ForEach y ver si es igual a yourCollection.Count - 1entonces estás en la última iteración.

Con un foreach, no puedes saber esto hasta que sea demasiado tarde (es decir, estás fuera del circuito).

Tenga en cuenta que asumo que está usando algo donde solo tiene una interfaz IEnumerable. Si tienes una lista, arrayetc. luego siga las otras respuestas aquí que usan .Count o similar 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 solo IEnumerable/IEnumerator, no hay forma de saber con certeza si hay más o no, si usa foreach.

Si necesita saber esto, use IEnumerable usted mismo, que es lo que hace foreach.

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

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

IEnumerator 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();

Esto imprimirá:

not last: 1
not last: 2
last: 3

El truco es tomar una copia del valor actual y luego pedirle al enumerador que intente pasar al siguiente. Si eso falla, la copia que hizo fue el último valor, de lo contrario, hay más.

Sección de Reseñas y Valoraciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *