Вопрос

Как определить, нахожусь ли я в последнем цикле оператора For Each в VB.NET?

Это было полезно?

Решение

Как правило, коллекции, с которыми вы можете работать For Each по реализации IEnumerator интерфейс.Этот интерфейс имеет только два метода: MoveNext и Reset и один объект недвижимости, Current.

В принципе, когда вы используете For Each в коллекции он вызывает MoveNext функцию и считывает возвращаемое значение.Если возвращаемое значение True, это означает, что в коллекции есть действительный элемент, и элемент возвращается через метод Current свойство.Если в коллекции больше нет элементов, MoveNext функция возвращает False и итерация завершается.

Из приведенного выше объяснения ясно, что For Each не отслеживает текущую позицию в коллекции и поэтому ответ на ваш вопрос краткий Нет.

Однако если вы все еще хотите узнать, находитесь ли вы на последнем элементе своей коллекции, вы можете попробовать следующий код.Он проверяет (с помощью LINQ), является ли текущий элемент последним.

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

Другие советы

Вероятно, было бы проще использовать цикл For вместо ForEach.Но аналогичным образом вы можете сохранить счетчик внутри цикла ForEach и посмотреть, равен ли он yourCollection.Count - 1, то вы находитесь на последней итерации.

При использовании foreach вы не сможете узнать это, пока не станет слишком поздно (т.ты не в теме).

Обратите внимание: я предполагаю, что вы используете что-то, где у вас есть только интерфейс IEnumerable.Если у вас есть список, массив и т.д.затем следуйте другим ответам здесь, в которых используется .Count или аналогичный, чтобы узнать, сколько элементов есть, и, таким образом, вы можете отслеживать, где вы находитесь в коллекции.

Однако, используя только IEnumerable/IEnumerator, невозможно точно узнать, есть ли еще, если вы используете foreach.

Если вам нужно это знать, используйте IEnumerable самостоятельно, что и делает foreach.

Приведенное ниже решение предназначено для C#, но его можно легко перевести на 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

Хитрость заключается в том, чтобы взять копию текущего значения, а затем попросить перечислитель попытаться перейти к следующему.Если это не помогло, значит, сделанная вами копия действительно была последним значением, в противном случае есть еще.

Короткий ответ:Ты не можешь

Длинный ответ:В семантике оператора For Each нет ничего, что позволяло бы вам определить, выполняете ли вы первую, последнюю или какую-либо конкретную итерацию.

For Each встроен в интерфейсы IEnumerable и IEnumerable<>, и его поведение зависит от вызываемой реализации.Для коллекции, которую вы повторяете, это справедливо, хотя и сбивает с толку, каждый раз возвращая элементы в другом порядке.К счастью, List<> этого не делает.

Если вам действительно нужно знать, что конкретная итерация является последней, вы можете определить последний элемент (заранее), а затем предпринять другие действия, когда встретите этот элемент.

Проще было бы обнаружить первый итерацию (скажем, через логическое значение), а затем сделайте что-то другое.

Пример (C#, но VB будет аналогичен):

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

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

Проверьте, является ли элемент последним элементом контейнера.

Почему вы хотите это сделать?
Вы можете просто разместить инструкции после цикла.(Что вы выполняете на последнем элементе)

Было бы проще использовать цикл For вместо ForEach, однако вы могли бы сделать что-то вроде

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

внутри вашего цикла ForEach...Предполагается, что объект правильно переопределил метод Equals.

Вероятно, это требует гораздо больше ресурсов, чем просто использование цикла For или отслеживание текущего индекса в отдельной переменной.

Я не уверен, что это правильный синтаксис, я давно не использовал VB.

Используя стандартный цикл «Для каждого», вы не сможете.Цель цикла «для каждого» — позволить вам сконцентрироваться на данных, а не на базовой коллекции.

Я постоянно возвращаюсь к этому посту, поэтому решил сесть и подумать об этой проблеме и пришел к следующему:

    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() на каждой итерации оказывает большое влияние на производительность, но вы всегда можете присвоить ее переменной вне цикла, если это не дает вам спать по ночам.

этот пример кода может помочь

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

Если вы привязаны к IEnumerable.Обязательно ли вам находиться внутри цикла foreach?Если нет, вы можете объявить переменную непосредственно перед циклом foreach.Установите его во время цикла.Затем используйте его после цикла (если он не равен нулю)

Ну, есть мало обходного пути, предположим, что вы работаете с 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     

вот простая вещь, я не знаю, политкорректна ли она, но она работает

for each item in listOfThings
   if(item = listOfThings.last)then 
       'you found the last loop
   end if
next 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top