¿Cómo se encuentra el último bucle en a Para Cada (VB.NET)?


¿Cómo puedo determinar si estoy en el bucle final de a Para Cada declaración en VB.NET?

Author: Mike B, 2008-12-18

12 answers

En general, las colecciones en las que se puede realizar For Each en la implementación de la IEnumerator interfaz. Esta interfaz tiene solo dos métodos, MoveNext y Reset y una propiedad, Current.

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

De la explicación anterior, está claro que el For Each no rastrea la posición actual en la colección y por lo tanto la respuesta a su pregunta es un breve 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
 47
Author: Alex Essilfie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-28 10:25:28

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

 12
Author: Strelok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 23:34:51

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

Nota, asumo que estás usando algo donde solo tienes una interfazumumerable. Si tiene una lista, matriz, etc. a continuación, siga las otras respuestas aquí que utiliza .Cuenta o similar para averiguar cuántos artículos hay, y así puedes llevar un registro de dónde estás en la colección.

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

Si necesita saber esto, use foreumerable 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<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();

Esto se imprimirá:

not last: 1
not last: 2
last: 3

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

 6
Author: Lasse Vågsæther Karlsen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-02 05:27:58

Respuesta corta: No puedes

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

Para cada uno está construido en las interfaces , y el comportamiento depende de la implementación que está llamando. Es válido, aunque confuso, para que la colección que estás iterando devuelva elementos en un orden diferente cada vez. Afortunadamente, Lista no hace esto.

Si realmente necesita saber que una iteración en particular es la última, podría identificar el último elemento (de antemano) y luego tomar una acción diferente cuando encuentre ese elemento.

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

Un ejemplo (C#, pero el VB será similar):

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

    result.Append(s);
    firstTime = false;
}
 2
Author: Bevan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-28 08:44:11

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

¿por Qué quieres hacer eso?
Podrías colocar instrucciones después del bucle. (Que se ejecuta en el último elemento)

 1
Author: Tom Wijsman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 23:29:17

Sería más fácil usar un bucle For en lugar de un ForEach, sin embargo, podría hacer algo como

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

Dentro de su bucle ForEach... Suponiendo que el objeto ha sobrescrito correctamente el método Equals.

Esto es probablemente mucho más intensivo en recursos que simplemente usar un bucle For o realizar un seguimiento del índice actual en una variable separada.

No estoy seguro de si esta es la sintaxis correcta, ha pasado mucho tiempo desde que usé VB.

 1
Author: Rex Morgan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 23:41:49

Usando un bucle estándar "Para cada" no puede. La intención de un bucle "para cada" es permitirle concentrarse en los datos en lugar de la colección subyacente.

 1
Author: JaredPar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 23:42:03

Sigo volviendo a este post, así que decidí sentarme y pensar en 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

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

 1
Author: Steven Liekens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-27 21:25:57

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
 1
Author: sh0hei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-20 09:19:39

Si está atado a IEnumerable. ¿Tienes que estar dentro del bucle Foreach? Si no, podría declarar una variable justo antes del bucle foreach. Póngalo durante el bucle. Luego, utilícelo después del bucle (si no es null)

 0
Author: Greg Dean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-17 23:36:34

Bueno, hay pocas soluciones Supongamos que está trabajando con CheckBoxList

Entonces 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     
 0
Author: panky sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-25 13:54:08

Aquí hay 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 
 0
Author: bobby shneider,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-10 15:22:51