【发布时间】:2009-06-04 17:56:52
【问题描述】:
我不相信传统方法可以做到这一点,但是像这样冗长的代码:
For Each s As String In myStringList Step -1
//' Do stuff here
Next
我可能必须在传统的 For..Each 循环之前反转 myString 对象,对吗?
【问题讨论】:
我不相信传统方法可以做到这一点,但是像这样冗长的代码:
For Each s As String In myStringList Step -1
//' Do stuff here
Next
我可能必须在传统的 For..Each 循环之前反转 myString 对象,对吗?
【问题讨论】:
我认为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 循环从末尾开始并向后工作。
【讨论】:
您必须执行以下操作:
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”,尽管在某些情况下会很好。
【讨论】:
遗憾的是,MSDN docs on For Each 声明 For Each 构造对于迭代顺序不重要的情况(无序集等)显式存在。所以不幸的是没有反转 For Each 的概念,因为无论如何都没有定义顺序。
祝你好运!
【讨论】:
调用System.Linq.Enumerable.Reverse 方法以与可枚举源相反的顺序获取IEnuemrable(Of TSource)。
【讨论】:
在Framework 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
【讨论】:
For Each s As String In myStringList.Reverse
//' Do stuff here
Next
【讨论】:
无法做到这一点的原因是,作为一项基本设计功能,For Each 可以迭代一个没有最后一个元素的可枚举对象,或者使用一个未知的最后一个元素。
【讨论】:
这行得通:
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
【讨论】:
你需要做的是用你之前的 for each 创建一个数组,然后使用 array.reverse 并在数组上运行 for each。完成
干杯
【讨论】:
根据循环内部发生的情况,您可以执行 .InsertAt(object,0) 而不是 .Add 并产生与反向枚举相同的结果。
【讨论】:
你可以给你想要反转的类添加一个扩展函数
<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
【讨论】:
首先你应该为每个语句创建一个列表(字符串),然后为 .. 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
希望对你有帮助
【讨论】:
接受的答案解释了原因,但要添加另一个示例,对于带有键的集合(SortedList、SortedDictionary、Dictionary 等),您可以这样做
For Each Id as Tkey in MyCollection.Keys.Reverse
// The item in question is now available as MyCollection(Id)
Next
【讨论】:
' 创建一个列表并逐步完成 For 循环收集
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
' 遍历逆序列表
for each objItem as ToolStripItem in revList
' do whatever (like removing your menu from an ArrayMenu)
next
' 用你需要的任何东西替换 ToolStripItem 和 Menu.DropDownItems
【讨论】: