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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/376437/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 13:57:50  来源:igfitidea点击:

How do you find the last loop in a For Each (VB.NET)?

vb.netforeachfor-loopeach

提问by RichC

How can I determine if I'm in the final loop of a For Each statement in VB.NET?

如何确定我是否处于 VB.NET 中 For Each 语句的最终循环中?

回答by Alex Essilfie

The generally, collections on which you can perform For Eachon implement the IEnumeratorinterface. This interface has only two methods, MoveNextand Resetand one property, Current.

通常,您可以在其For Each上执行的集合实现IEnumerator接口。此接口只有两个方法,MoveNextReset和一个属性,Current

Basically, when you use a For Eachon a collection, it calls the MoveNextfunction and reads the value returned. If the value returned is True, it means there is a valid element in the collection and element is returned via the Currentproperty. If there are no more elements in the collection, the MoveNextfunction returns Falseand the iteration is exited.

基本上,当您For Each在集合上使用 a时,它会调用该MoveNext函数并读取返回的值。如果返回的值为True,则表示集合中存在有效元素,并且元素通过Current属性返回。如果集合中没有更多元素,则MoveNext函数返回False并退出迭代。

From the above explanation, it is clear that the For Eachdoes not track the current position in the collection and so the answer to your question is a short No.

从上面的解释中,很明显For Each不跟踪集合中的当前位置,因此您的问题的答案是一个简短的No

If, however, you still desire to know if you're on the last element in your collection, you can try the following code. It checks (using LINQ) if the current item is the last item.

但是,如果您仍然想知道自己是否在集合中的最后一个元素上,则可以尝试以下代码。它检查(使用 LINQ)当前项是否是最后一项。

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

回答by Strelok

It probably would be easier to just use a For loop instead of ForEach. But, similarly, you could keep a counter inside your ForEach loop and see if its equal to yourCollection.Count - 1, then you are in the last iteration.

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

回答by Lasse V. Karlsen

With a foreach, you cannot know this until it is too late (ie. you're out of the loop).

使用 foreach,您无法知道这一点,直到为时已晚(即,您已退出循环)。

Note, I'm assuming you're using something where you only have an IEnumerable interface. If you have a list, array, etc. then follow the other answers here which uses .Count or similar to find out how many items there are, and thus you can keep track of where you are in the collection.

请注意,我假设您正在使用只有 IEnumerable 接口的东西。如果您有一个列表、数组等,那么请按照此处使用 .Count 或类似方法的其他答案来找出有多少项目,因此您可以跟踪您在集合中的位置。

However, with just IEnumerable/IEnumerator, there is no way to know for sure wether or not there are more, if you use foreach.

但是,仅使用 IEnumerable/IEnumerator,如果您使用 foreach,则无法确定是否还有更多。

If you need to know this, use IEnumerable yourself, which is what foreach does.

如果您需要知道这一点,请自己使用 IEnumerable,这就是 foreach 所做的。

The below solution is for C# but should translate easily to VB.NET:

以下解决方案适用于 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();

This will print:

这将打印:

not last: 1
not last: 2
last: 3

The trick is to take a copy of the current value, then ask the enumerator to attempt to move on to the next one. If that fails, the copy you made was indeed the last value, otherwise there is more.

诀窍是获取当前值的副本,然后让枚举器尝试移动到下一个值。如果失败,则您制作的副本确实是最后一个值,否则还有更多。

回答by Bevan

Short answer: You can't

简短的回答:你不能

Long answer: There's nothing in the semantics of a For Each statement that allows you to identify whether you're running the first, last or any particular iteration.

长答案: For Each 语句的语义中没有任何内容可以让您确定您正在运行的是第一次、最后一次还是任何特定的迭代。

For Each is built in the IEnumerable and IEnumerable<> interfaces, and the behavior is dependent on the implementation you're calling. It's valid, though confusing, for the collection you're iterating to return elements in a different order every time. Fortunately, List<> doesn't do this.

For Each 内置于 IEnumerable 和 IEnumerable<> 接口中,其行为取决于您正在调用的实现。尽管令人困惑,但对于您每次迭代以不同顺序返回元素的集合来说,这是有效的。幸运的是, List<> 不会这样做。

If you really need to know that a particular iteration is the last, you could identify the last element (in advance) and then take different action when you encounter that element.

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

Easier would be to detect the firstiteration (say, through a boolean) and then do something different.

更容易检测第一次迭代(例如,通过布尔值),然后做一些不同的事情。

An example (C#, but the VB will be similar):

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

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

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

回答by Rex Morgan

It would be easier to use a For loop instead of a ForEach, however you could do something like

使用 For 循环而不是 ForEach 会更容易,但是您可以执行以下操作

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

inside of your ForEach loop... Assuming the object has properly overridden the Equals method.

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

This is probably much more resource intensive than just using a For loop or keeping track of the current index in a separate variable.

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

I'm not sure if this is the correct syntax, it's been a long time since I've used VB.

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

回答by JaredPar

Using a standard "For Each" loop you can't. The intent of a "for Each" loop is to allow you to concentrate on the data in lieu of the underlying collection.

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

回答by Tamara Wijsman

Check if the element is the last element of the container.

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

Why do you want to do that?
You could just place instructions after the loop. (That you execute on the last element)

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

回答by Steven Liekens

I keep coming back to this post, so I decided to sit down and think about this issue and I came up with this:

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

    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

You could even reduce the If...Then...End Ifstatement to a single line if you wanted to. I'm not sure if calling .Last()on every iteration has a large impact on performance, but you can always assign it to a variable outside of the loop if that's what keeps you awake at night.

如果您愿意,您甚至可以将If...Then...End If语句缩减为一行。我不确定调用.Last()每次迭代是否对性能有很大影响,但如果这让你夜不能寐,你总是可以将它分配给循环外的变量。

回答by sh0hei

this code sample might help

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

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

回答by bobby shneider

here is a simple thing i dont know if it is politically correct but it works

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

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