有可能做一个For ...每个循环倒退吗?

时间:2009-06-04 17:56:53

标签: vb.net for-loop

我不相信传统方法可以做到这一点,但是像这个冗长的代码:

For Each s As String In myStringList Step -1
    //' Do stuff here
Next

我可能不得不在传统的For..Each循环之前反转myString对象,对吗?

14 个答案:

答案 0 :(得分:43)

我认为Mike's answer below中引用的文档非常具有误导性。 For Each的顺序由它所调用的集合定义(即它的IEnumerable / IEnumerable<T>的实现),但与说它不应该'相同'在订单很重要时使用。许多集合(例如数组,List<T>等)总是按照“自然”顺序进行。

部分文件确实提到了这一点:

  

遍历顺序。当你执行一个   For Each ... Next循环,遍历   收藏是在的控制下   由...返回的枚举器对象   GetEnumerator方法。的顺序   遍历不是由Visual确定的   基本的,而是由MoveNext   枚举器对象的方法。这个   意味着你可能无法做到   预测哪个元素   集合是第一个被退回   在元素中,或者是下一个   在给定元素之后返回。

这完全不同于说不能依赖它 - 如果您知道您正在迭代的集合将以所需的顺序生成结果,则可以依赖 。它不像是随意挑选元素。 IEnumerable / IEnumerable<T>方面的行为在该页面上明确定义。

可预测排序的最重要的例外是字典和集合,它们自然是无序的。

要反转IEnumerable<T>,请使用Enumerable.Reverse - 但如果您需要在按位置索引的集合(例如数组或List<T>)上进行反向迭代,那么它会从末尾开始使用For循环并向后工作会更有效率。

答案 1 :(得分:37)

你必须做类似的事情:

For i as integer = myStringList.Count-1 to 0 step -1
    dim s as string = myStringList.Item(i)
    ' Do your stuff with s
Next i

但据我所知,你不能向后做“For ... Each”,尽管在一些情况下会很好。

答案 2 :(得分:13)

可悲的是,MSDN docs on For Each表明For Each构造明确存在于迭代顺序不重要(无序集等)的情况。因此,遗憾的是没有反转For Each的概念,因为无论如何都没有定义订单。

祝你好运!

答案 3 :(得分:12)

调用System.Linq.Enumerable.Reverse方法,以与您的可枚举来源相反的顺序获得IEnuemrable(Of TSource)

答案 4 :(得分:3)

For Each s As String In myStringList.Reverse
    //' Do stuff here
Next

答案 5 :(得分:3)

在框架4中测试,代码

For Each s As String In myStringList.Reverse
    //' Do stuff here
Next

它不起作用,正确的方法是:

myStringList.Reverse() ' it is a method not a function
For Each s As String In myStringList
//' Do stuff here
Next

请注意:MSDN: Reserve

答案 6 :(得分:1)

无法完成的原因是,作为一个基本的设计特征,For Each可以迭代一个没有最后一个元素的枚举,或者一个尚未知的最后一个元素。

答案 7 :(得分:0)

你要做的就是用你以前的每一个创建一个数组,然后使用array.reverse并在数组上运行for each。完成

干杯

答案 8 :(得分:0)

根据循环内部的情况,您可以执行.InsertAt(object,0)而不是.Add,并生成与反向枚举相同的结果。

答案 9 :(得分:0)

您可以将扩展函数添加到您要反转的类

<Serializable()> Public Class SomeCollection
    Inherits CollectionBase
    Public Sub New()
    End Sub

    Public Sub Add(ByVal Value As Something)
        Me.List.Add(Value)
    End Sub

    Public Sub Remove(ByVal Value As Something)
        Me.List.Remove(Value)
    End Sub

    Public Function Contains(ByVal Value As Something) As Boolean
        Return Me.List.Contains(Value)
    End Function

    Public Function Item(ByVal Index As Integer) As Something
        Return DirectCast(Me.List.Item(Index), Something)
    End Function

    Public Function Reverse() As SomeCollection
        Dim revList As SomeCollection = New SomeCollection()
        For index As Integer = (Me.List.Count - 1) To 0 Step -1
             revList.List.Add(Me.List.Item(index))
        Next
        Return revList
    End Function
End Class

然后你会这样称呼它

For Each s As Something In SomeCollection.Reverse

Next

答案 10 :(得分:0)

首先你应该为每个语句创建一个(字符串)列表,然后为... step -1 ..next语句创建另一个法线。看一个例子:

Dim ff As New List(Of Integer)
For Each rRow As DataRow In DeletedRows
Dim item As Integer
item = rRow.Table.Rows.IndexOf(rRow)
ff.Add(item)
Next
For i As Integer = ff.Count - 1 To 0 Step -1
dim item as integer=ff(i)
next i

我希望有所帮助

答案 11 :(得分:0)

接受的答案解释了为什么,但为了添加另一个例子,对于带有键的集合(SortedList,SortedDictionary,Dictionary等),你可以做到

For Each Id as Tkey in MyCollection.Keys.Reverse
   // The item in question is now available as MyCollection(Id)
Next

答案 12 :(得分:0)

&#39;创建一个列表,并逐步完成For Loop Collecting

dim revList as New List (of ToolStripItem)  
For each objItem as ToolStripItem in Menu.DropDownItems
    revList.Add(objItem)
next
revList.reverse ' reverse the order of that list

&#39;逐步通过反向排序列表

for each objItem as ToolStripItem in revList   
    ' do whatever (like removing your menu from an ArrayMenu)
next

&#39;用你需要的任何东西替换ToolStripItem和Menu.DropDownItems

答案 13 :(得分:0)

这有效:

Dim myArray() As String = {"1", "2", "3", "4", "5"}

For Each n As String In myArray.Reverse
    Debug.Print(n)
Next

输出:5 4 3 2 1

'

这也有效:

Dim myArray() As String = {"1", "2", "3", "4", "5"}

For i As Integer = myArray.Length - 1 To 0 Step -1
    Debug.Print(myArray(i))
Next

输出:5 4 3 2 1