Comment trouver la dernière boucle en a pour chacun (VB.NET)?

Comment puis-je déterminer si je suis dans la boucle finale de a pour chaque déclaration VB.NET?

22
demandé sur Mike B 2008-12-18 02:26:36

12 réponses

généralement, les collections sur lequel vous pouvez effectuer For Each mettre en œuvre le IEnumerator interface. Cette interface n'a que deux méthodes, MoveNext et Reset et une propriété, Current.

en gros, quand vous utilisez un For Each sur une collection, il appelle la MoveNext fonction et lit la valeur retournée. Si la valeur renvoyée est True, cela signifie qu'il ya un élément valide dans la collecte et l'élément est renvoyé via Current propriété. Si il n'y a pas plus d'éléments dans la collection, le MoveNext renvoie la fonction False et l'itération est sorti.

D'après l'explication ci-dessus, il est clair que le For Each ne pas suivre la position actuelle dans la collection et donc la réponse à votre question est un court Aucun.

si, cependant, vous désirez toujours savoir si vous êtes sur le dernier élément de votre collection, vous pouvez essayer le code suivant. Il vérifie (en utilisant LINQ) si le courant l'élément est le dernier élément.

For Each item in Collection
    If item Is Collection.Last Then
        'do something with your last item'
    End If
Next
47
répondu Alex Essilfie 2010-10-28 10:25:28

il serait probablement plus facile d'utiliser un For loop au lieu d'un ForEach. Mais, de la même façon, vous pourriez garder un compteur à l'intérieur de votre boucle de ForEach et voir si son égal à yourCollection.Count - 1, alors vous êtes dans la dernière itération.

12
répondu Strelok 2008-12-17 23:34:51

Avec un foreach, vous ne pouvez pas savoir jusqu'à ce qu'il soit trop tard (c'est à dire. vous êtes hors de la boucle).

Note, je suppose que vous utilisez quelque chose où vous n'avez qu'une interface Ienumérable. Si vous avez une liste, tableau, etc. suivez ensuite les autres réponses ici qui utilise .Comptez ou similaire pour savoir combien d'articles Il ya, et donc vous pouvez garder une trace de l'endroit où vous êtes dans la collection.

cependant, avec juste IEnumerable / IEnumerator, il n'y a aucun moyen de savoir avec certitude qu'il y en ait plus ou non, si vous utilisez foreach.

si vous avez besoin de savoir cela, utilisez IEnumerable vous-même, qui est ce que foreach fait.

la solution CI-DESSOUS est pour C# mais devrait traduire facilement 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();

imprimer:

not last: 1
not last: 2
last: 3

Le truc est de prendre une copie de la valeur actuelle, puis demandez à l'agent recenseur pour tenter de passer à la suivante. Si cela échoue, la copie que vous avez faite était bien la dernière valeur, sinon il y a plus.

6
répondu Lasse Vågsæther Karlsen 2015-01-02 05:27:58

brève réponse: vous ne pouvez pas

réponse longue: il n'y a rien dans la sémantique d'un énoncé pour chaque énoncé qui vous permet d'identifier si vous exécutez la première, la dernière ou une itération particulière.

pour chacun est construit dans les interfaces IEnumerable et IEnumerable<>, et le comportement dépend de l'implémentation que vous appelez. Il est valide, bien que déroutant, pour la collection que vous itérez de retourner des éléments dans un ordre différent à chaque fois. Heureusement, List<> ne fait pas cela.

Si vous avez vraiment besoin de savoir qu'une itération particulière est la dernière, vous pouvez identifier le dernier élément (à l'avance) et ensuite prendre des mesures différentes, lorsque vous rencontrez cet élément.

plus Facile serait de détecter l' premier itération (disons, à travers un booléen) et ensuite faire quelque chose de différent.

Un exemple (C#, VB seront similaires):

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

    result.Append(s);
    firstTime = false;
}
2
répondu Bevan 2010-10-28 08:44:11

Vérifier si l'élément est le dernier élément du conteneur.

Pourquoi voulez-vous faire?

Vous pourriez juste placer des instructions après la boucle. (Que vous exécutez sur le dernier élément)

1
répondu Tom Wijsman 2008-12-17 23:29:17

Il serait plus facile d'utiliser une boucle For au lieu d'une ForEach, cependant vous pouvez faire quelque chose comme

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

à l'intérieur de votre boucle de ForEach... En supposant que l'objet a correctement dépassé la méthode des égaux.

c'est probablement beaucoup plus exigeant en ressources que de simplement utiliser une boucle pour Ou garder une trace de l'indice courant dans une variable séparée.

Je ne suis pas sûr que ce soit la bonne syntaxe, ça fait longtemps que je n'ai pas utilisé VB.

1
répondu Rex Morgan 2008-12-17 23:41:49

en utilisant un "pour chaque" boucle standard vous ne pouvez pas. L'objectif d'une boucle" pour chaque " est de vous permettre de vous concentrer sur les données au lieu de la collecte sous-jacente.

1
répondu JaredPar 2008-12-17 23:42:03

j'en reviens à ce post, j'ai donc décidé de s'asseoir et de réfléchir à cette question et j'ai trouvé ceci:

    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

Vous pouvez même réduire le If...Then...End If déclaration d'une seule ligne, si vous vouliez. Je ne suis pas sûr si vous appelez .Last() sur chaque itération a un grand impact sur la performance, mais vous pouvez toujours l'affecter à une variable en dehors de la boucle si c'est ce qui vous garde éveillé la nuit.

1
répondu Steven Liekens 2013-02-27 21:25:57

cet exemple de code peut aider

For Each item in Collection
  If ReferenceEquals(Collection.Item(Collection.Count - 1), item) Then
    'do something with your last item'
  End If
Next
1
répondu sh0hei 2013-12-20 09:19:39

si vous êtes lié à IEnumerable. Est-ce que tu dois être dans la boucle de l'avant-main? Si non, vous pouvez déclarer une variable juste avant la boucle foreach. Définir au cours de la boucle. Puis, l'utiliser après la boucle (si ce n'est pas null)

0
répondu Greg Dean 2008-12-17 23:36:34

eh Bien il y a peu de solution de contournement Supposons que vous travaillez avec CheckBoxList

Puis cet exemple de code qui pourrait aider :

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
répondu panky sharma 2012-07-25 13:54:08

voici une chose simple que je ne sais pas si elle est politiquement correcte mais elle fonctionne

for each item in listOfThings
   if(item = listOfThings.last)then 
       'you found the last loop
   end if
next 
0
répondu bobby shneider 2018-01-10 15:22:51