你如何在For Each(VB.NET)中找到最后一个循环?

时间:2008-12-17 23:26:37

标签: vb.net foreach for-loop each

如何判断我是否处于VB.NET中For Each语句的最后一个循环中?

13 个答案:

答案 0 :(得分:53)

您可以执行IEnumerator接口的一般集合For Each。此界面只有两个方法MoveNextReset以及一个属性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

答案 1 :(得分:13)

使用For循环而不是ForEach可能会更容易。但是,类似地,你可以在ForEach循环中保留一个计数器,看它是否等于yourCollection.Count - 1,那么你就是在最后一次迭代中。

答案 2 :(得分:6)

对于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

诀窍是获取当前值的副本,然后要求枚举器尝试继续下一个。如果失败了,你制作的副本确实是最后一个值,否则还有更多。

答案 3 :(得分:2)

简短回答:你不能

答案很长:For Each语句的语义中没有任何内容可以让您识别您是在运行第一个,最后一个还是任何特定的迭代。

For Each内置于IEnumerable和IEnumerable&lt;&gt;接口,行为取决于您正在调用的实现。对于您每次都以不同顺序返回元素的集合,它是有效的,虽然令人困惑。幸运的是,List&lt;&gt;不这样做。

如果您确实需要知道特定的迭代是最后一个,您可以(提前)识别最后一个元素,然后在遇到该元素时采取不同的操作。

更容易检测第一次迭代(例如,通过布尔值),然后执行不同的操作。

一个例子(C#,但VB类似):

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

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

答案 4 :(得分:1)

检查元素是否是容器的最后一个元素。

为什么要这样做?
你可以在循环后放置指令。 (你在最后一个元素上执行)

答案 5 :(得分:1)

使用For循环而不是ForEach会更容易,但是你可以使用

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

在ForEach循环内部...假设对象已正确覆盖Equals方法。

这可能比仅仅使用For循环或在单独的变量中跟踪当前索引更加耗费资源。

我不确定这是否是正确的语法,自从我使用VB以来已经很长时间了。

答案 6 :(得分:1)

使用标准的“For Each”循环,你不能。 “for Each”循环的目的是让您专注于数据而不是底层集合。

答案 7 :(得分:1)

我一直回到这篇文章,所以我决定坐下来思考这个问题,我想出了这个:

    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()是否会对性能产生很大影响,但是你总是可以将它分配给循环外的一个变量,如果这是让你夜不能寐的话。

答案 8 :(得分:1)

此代码示例可能会有所帮助

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

答案 9 :(得分:0)

如果你被绑定到IEnumerable。你必须进入foreach循环吗?如果没有,你可以在foreach循环之前声明一个变量。在循环期间设置它。然后,在循环之后使用它(如果它不为空)

答案 10 :(得分:0)

好的解决方法很少 假设您正在使用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     

答案 11 :(得分:0)

这是一个简单的事情,我不知道它是否在政治上是正确的,但它的确有效

for each item in listOfThings
   if(item = listOfThings.last)then 
       'you found the last loop
   end if
next 

答案 12 :(得分:0)

For Each xObj In xColl
    If xObj = xColl(xColl.Count) Then ...
Next