Domanda

Come è possibile determinare se sono nel ciclo finale di una per ogni istruzione in VB.NET?

È stato utile?

Soluzione

Il generale, raccolte su cui è possibile eseguire For Each sul implementare il IEnumerator interfaccia. Questa interfaccia ha solo due metodi, MoveNext e Reset e una proprietà, Current.

In sostanza, quando si utilizza un For Each su una collezione, si chiama la funzione MoveNext e legge il valore restituito. Se il valore restituito è True, significa che c'è un elemento valido nella raccolta e l'elemento viene restituito tramite la proprietà Current. Se non ci sono più elementi della collezione, la funzione restituisce MoveNext False e l'iterazione si esce.

Da quanto sopra esposto, è chiaro che il For Each non tiene la posizione attuale nella raccolta e quindi la risposta alla tua domanda è un breve No .

Se, tuttavia, è ancora il desiderio di sapere se sei l'ultimo elemento nella vostra collezione, è possibile provare il seguente codice. Esso controlla (utilizzando LINQ) se l'elemento corrente è l'ultimo elemento.

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

Altri suggerimenti

Probabilmente sarebbe stato più facile usare solo un ciclo For invece di ForEach. Ma, allo stesso modo, si potrebbe tenere un contatore all'interno del vostro ciclo ForEach e vedere se il suo pari a yourCollection.Count - 1, allora siete nel l'ultima iterazione.

Con un foreach, non puoi sapere questo fino a quando non è troppo tardi (es. Sei fuori dal giro).

Nota, sto supponendo che si sta utilizzando qualcosa in cui si ha solo un'interfaccia IEnumerable. Se si dispone di un elenco, array, ecc quindi seguire le altre risposte qui che utilizza Count o simile per scoprire quanti oggetti ci sono, e quindi si può tenere traccia di dove ci si trova nella collezione.

Tuttavia, con solo IEnumerable / IEnumerator, non c'è modo di sapere con certezza montone castrato o no ci sono più, se si utilizza foreach.

Se avete bisogno di sapere questo, utilizzare IEnumerable te stesso, che è ciò che fa foreach.

La soluzione qui di seguito è per C #, ma dovrebbe tradursi facilmente in 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();

Questa stampa volontà:

not last: 1
not last: 2
last: 3

Il trucco è quello di prendere una copia del valore corrente, poi chiedere l'enumeratore per tentare di passare a quello successivo. Se non funziona, la copia che hai fatto era davvero l'ultimo valore, altrimenti non c'è più.

Risposta breve: non è possibile

Risposta lunga: Non c'è niente nella semantica di una per ogni istruzione che permette di identificare se si sta eseguendo il primo, ultimo o una particolare iterazione.

Per ogni è costruito nel IEnumerable e IEnumerable <> interfacce, e il comportamento dipende dalla realizzazione si sta chiamando. E 'valida, anche se confusa, per la raccolta si sta iterazione di restituire gli elementi in un ordine diverso ogni volta. Fortunatamente, List <> non fa questo.

Se avete veramente bisogno di sapere che una particolare iterazione è l'ultimo, si potrebbe identificare l'ultimo elemento (in anticipo) e poi agire diverso quando si incontra questo elemento.

Più facile sarebbe quella di rilevare il prima iterazione (ad esempio, attraverso un valore booleano) e poi fare qualcosa di diverso.

Un esempio (C #, ma il VB saranno simili):

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

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

Controlla se l'elemento è l'ultimo elemento del contenitore.

Perché vuoi farlo?
Si potrebbe semplicemente inserire le istruzioni dopo il ciclo. (Che si esegue l'ultimo elemento)

Sarebbe più facile da utilizzare un ciclo For invece di un ForEach, tuttavia si potrebbe fare qualcosa di simile

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

all'interno del vostro ciclo ForEach ... Supponendo che l'oggetto ha correttamente ignorato il metodo Equals.

Questo è probabilmente molto più risorse rispetto solo utilizzando un ciclo For o tenere traccia dell'indice corrente in una variabile separata.

Non sono sicuro se questa è la sintassi corretta, è passato molto tempo da quando ho usato VB.

Utilizzo di uno standard "per ogni" ciclo non si può. L'intento di un "per ogni" ciclo è quello di permettere di concentrarsi sui dati al posto della collezione sottostante.

Continuo a tornare a questo post, così ho deciso di sedermi e pensare a questo problema e mi si avvicinò con questo:

    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

Si potrebbe anche ridurre la dichiarazione If...Then...End If a una singola linea se si voleva. Io non sono sicuro se chiamare .Last() ad ogni iterazione ha un grande impatto sulle prestazioni, ma si può sempre assegnarlo a una variabile al di fuori del ciclo se è questo che ti tiene sveglio la notte.

questo esempio di codice potrebbe aiutare

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

Se si sono legati a IEnumerable. Dovete essere all'interno del ciclo foreach? Se non si poteva dichiarare una variabile poco prima del ciclo foreach. Impostare durante il ciclo. Quindi, utilizzare dopo il ciclo (se non nullo)

Beh ci sono pochi soluzione Supponiamo che si sta lavorando con CheckBoxList

Quindi questo esempio di codice potrebbe aiutare:

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     

qui è una cosa semplice non so se è politicamente corretto ma funziona

for each item in listOfThings
   if(item = listOfThings.last)then 
       'you found the last loop
   end if
next 
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top