Question

Comment puis-je déterminer si je suis dans la dernière boucle d'une instruction For Each en VB.NET?

Était-ce utile?

La solution

Le général, les collections sur lequel vous pouvez effectuer For Each sur la mise en œuvre IEnumerator . Cette interface ne comporte que deux méthodes, MoveNext et Reset et une propriété, Current.

En fait, lorsque vous utilisez un For Each sur une collection, il appelle la fonction MoveNext et lit la valeur retournée. Si la valeur retournée est True, cela signifie qu'il ya un élément valable dans la collecte et l'élément est retourné par la propriété Current. S'il n'y a pas plus d'éléments de la collection, le rendement de la fonction MoveNext False et l'itération est terminé.

De l'explication ci-dessus, il est clair que la For Each ne suit pas la position actuelle dans la collection et ainsi de la réponse à votre question est une courte Non .

Si, toutefois, vous désirez encore savoir si vous êtes sur le dernier élément de votre collection, vous pouvez essayer le code suivant. Il vérifie (LINQ) si l'élément en cours 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

Autres conseils

Il serait probablement plus facile d'utiliser simplement une boucle For au lieu de ForEach. Mais, de même, vous pouvez garder un compteur dans votre boucle foreach et voir si son égal à yourCollection.Count - 1, alors vous êtes dans la dernière itération.

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

Remarque, je suppose que vous utilisez quelque chose où vous avez seulement une interface IEnumerable. Si vous avez une liste, un tableau, etc., puis suivez les autres réponses ici qui utilise .Count ou similaire pour savoir combien d'articles il y a, et donc vous pouvez garder une trace de l'endroit où vous êtes dans la collection.

Cependant, avec seulement IEnumerable / IEnumerator, il n'y a aucun moyen de savoir à coup sûr si oui ou non il y a plus, si vous utilisez foreach.

Si vous avez besoin de savoir cela, utilisez IEnumerable vous, ce qui est foreach fait.

La solution ci-dessous pour C #, mais devrait se 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();

Cette impression volonté:

not last: 1
not last: 2
last: 3

L'astuce est de prendre une copie de la valeur actuelle, puis demander au recenseur pour tenter de passer à la suivante. Si cela échoue, la copie que vous avez fait était en effet la dernière valeur, sinon il y a plus.

Réponse courte: Vous ne pouvez pas

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

Pour Chacun est construit dans les interfaces IEnumerable et IEnumerable <>, et le comportement dépend de la mise en œuvre que vous appelez. Il est valide, si déroutant, pour la collection que vous nous parcourons de retourner des éléments dans un ordre différent à chaque fois. Heureusement, Liste <> ne le fait pas.

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 prendre des mesures différentes lorsque vous rencontrez cet élément.

serait plus facile de détecter la premier itération (par exemple, par un booléen) puis faire quelque chose de différent.

Un exemple (C #, mais le VB sera similaire):

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

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

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

Pourquoi voulez-vous faire cela?
Vous pouvez placer des instructions juste après la boucle. (Que vous exécutez sur le dernier élément)

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

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

à l'intérieur de la boucle foreach ... En supposant que l'objet a correctement substituée la méthode Equals.

Ceci est probablement beaucoup plus de ressources que d'utiliser une boucle For ou garder une trace de l'indice actuel dans une variable séparée.

Je ne sais pas si cela est la syntaxe correcte, il a été longtemps que je l'ai utilisé VB.

L'utilisation d'un standard « pour chaque » boucle vous ne pouvez pas. Le but d'une boucle « pour chaque » est de vous permettre de vous concentrer sur les données en lieu et place de la collection sous-jacente.

Je reviens à ce poste, donc je décidé de s'asseoir et de réfléchir à cette question et je suis venu avec 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 la déclaration de If...Then...End If à une seule ligne si vous vouliez. Je ne sais pas si vous appelez .Last() à chaque itération a un impact important sur les performances, mais vous pouvez toujours l'assigner à une variable en dehors de la boucle si c'est ce que vous empêche de dormir la nuit.

cet exemple de code pourrait aider

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

Si vous êtes lié à IEnumerable. Avez-vous être à l'intérieur de la boucle de foreach? Sinon, vous pouvez déclarer une variable juste avant la boucle foreach. Réglez-le pendant la boucle. Puis, l'utiliser après la boucle (si son non nul)

Eh bien il y a quelques solution Supposons que vous travaillez avec CheckBoxList

Ensuite, cet exemple de code 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     

ici est une chose simple que je ne sais pas s'il est politiquement correct, mais cela fonctionne

for each item in listOfThings
   if(item = listOfThings.last)then 
       'you found the last loop
   end if
next 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top