Как я могу определить, находится ли я в последнем цикле выражения For Each в VB.NET?
Как вы находите последний цикл в "Для каждого" (VB.NET)?
Ответ 1
Как правило, коллекции, на которых вы можете выполнить For Each
, реализовать интерфейс IEnumerator
. Этот интерфейс имеет только два метода: MoveNext
и Reset
и одно свойство Current
.
В основном, когда вы используете For Each
в коллекции, он вызывает функцию MoveNext
и считывает возвращаемое значение. Если возвращаемое значение равно True
, это означает, что в коллекции есть допустимый элемент, а элемент возвращается через свойство Current
. Если в коллекции больше нет элементов, функция MoveNext
возвращает False
, и итерация завершается.
Из приведенного выше объяснения ясно, что For Each
не отслеживает текущую позицию в коллекции, и поэтому ответ на ваш вопрос - короткий No.
Если, однако, вы все еще хотите знать, находитесь ли вы в последнем элементе в своей коллекции, вы можете попробовать следующий код. Он проверяет (используя LINQ), если текущий элемент является последним.
For Each item in Collection
If item Is Collection.Last Then
'do something with your last item'
End If
Next
Ответ 2
Вероятно, было бы проще просто использовать цикл For вместо ForEach. Но, аналогично, вы могли бы держать счетчик внутри своего цикла ForEach и видеть, равно ли ему yourCollection.Count - 1
, то вы находитесь в последней итерации.
Ответ 3
С помощью foreach вы не можете знать это, пока не станет слишком поздно (т.е. вы вышли из цикла).
Заметьте, я предполагаю, что вы используете что-то, где у вас есть только интерфейс IEnumerable. Если у вас есть список, массив и т.д., То следуйте другим ответам здесь, где используется .Count или аналогично, чтобы узнать, сколько там элементов, и, следовательно, вы можете отслеживать, где вы находитесь в коллекции.
Однако, с помощью только IEnumerable/IEnumerator, нет никакого способа узнать наверняка, или нет, если вы используете foreach.
Если вам нужно это знать, используйте IEnumerable самостоятельно, что и делает foreach.
Ниже приведено решение для С#, но должно легко перевести его на 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();
Это напечатает:
not last: 1
not last: 2
last: 3
Хитрость заключается в том, чтобы взять копию текущего значения, а затем попросить перечислитель попытаться перейти к следующему. Если это не удается, копия, которую вы сделали, действительно была последним значением, в противном случае больше.
Ответ 4
Короткий ответ: вы не можете
Длинный ответ: в семантике оператора For Each нет ничего, что позволяет определить, запускаете ли вы первую, последнюю или какую-либо конкретную итерацию.
Для каждого встроен интерфейс IEnumerable и IEnumerable < > , и поведение зависит от реализации, которую вы вызываете. Это действительно, хотя и запутанно, для коллекции, которую вы итерируете, чтобы возвращать элементы в другом порядке каждый раз. К счастью, List < > не делает этого.
Если вам действительно нужно знать, что конкретная итерация является последней, вы можете определить последний элемент (заранее), а затем предпринять различные действия, когда вы сталкиваетесь с этим элементом.
Легче было бы обнаружить первую итерацию (скажем, через логическое), а затем сделать что-то другое.
Пример (С#, но VB будет похож):
StringBuilder result = new StringBuilder();
bool firstTime = true;
foreach(string s in names)
{
if (!firstTime)
{
result.Append(", ");
}
result.Append(s);
firstTime = false;
}
Ответ 5
Проверьте, является ли элемент последним элементом контейнера.
Почему вы хотите это сделать?
Вы можете просто разместить инструкции после цикла. (Что вы выполняете на последнем элементе)
Ответ 6
Было бы проще использовать цикл For вместо ForEach, однако вы могли бы сделать что-то вроде
If item.Equals(itemCollection(itemCollection.Count)) Then
...
End If
внутри вашего цикла ForEach... Предполагая, что объект правильно переопределил метод Equals.
Это, вероятно, гораздо более ресурсоемкий, чем просто использование цикла For или отслеживание текущего индекса в отдельной переменной.
Я не уверен, что это правильный синтаксис, я долгое время использовал VB.
Ответ 7
Используя стандартный цикл "Для каждого", вы не можете. Цель цикла "для каждого" заключается в том, чтобы вы могли сосредоточиться на данных вместо базовой коллекции.
Ответ 8
Я возвращаюсь на этот пост, поэтому решил сесть и подумать об этом, и я придумал это:
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
Вы даже можете уменьшить оператор If...Then...End If
до одной строки, если хотите. Я не уверен, что вызов .Last()
на каждой итерации сильно влияет на производительность, но вы всегда можете назначить ее переменной вне цикла, если это то, что заставляет вас спать по ночам.
Ответ 9
этот пример кода может помочь
For Each item in Collection
If ReferenceEquals(Collection.Item(Collection.Count - 1), item) Then
'do something with your last item'
End If
Next
Ответ 10
Если вы привязаны к IEnumerable. Вы должны находиться внутри цикла foreach? Если нет, вы можете объявить переменную непосредственно перед циклом foreach. Установите его во время цикла. Затем используйте его после цикла (если его не null)
Ответ 11
Ну, есть немного обходных решений Предположим, вы работаете с CheckBoxList
Тогда этот пример кода может помочь:
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
Ответ 12
вот простая вещь, я не знаю, является ли она политически корректной, но она работает
for each item in listOfThings
if(item = listOfThings.last)then
'you found the last loop
end if
next