web-dev-qa-db-ja.com

For ... Eachループを逆方向に実行することはできますか?

私はこれが従来の方法で可能であるとは思わないが、この冗長なコードのようなもの:

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

従来のFor..Eachループの前にmyStringオブジェクトを反転する必要があるでしょう。

34
Anders

以下のマイクの回答 で参照されているドキュメントはextremely誤解を招くものだと思います。 For Eachの順序は、呼び出されるコレクション(つまり、IEnumerable/IEnumerable<T>の実装)によって定義されますが、それはnotと同じです順序が重要な場合は使用しないでください。多くのコレクション(配列、List<T>など)は常に「自然な」順序で実行されます。

ドキュメントの一部はこれを暗示しています:

トラバーサル注文。 For Each ... Nextループを実行すると、コレクションの走査はGetEnumeratorメソッドによって返される列挙子オブジェクトの制御下にあります。走査の順序はVisual Basicではなく、列挙子オブジェクトのMoveNextメソッドによって決定されます。これは、コレクションのどの要素がelementで最初に返されるか、または特定の要素の次に返される次の要素を予測できない場合があることを意味します。

それは信頼できないと言うのとまったく同じではありません-信頼できます繰り返し処理しているコレクションが望ましい順序で結果を生成することがわかっている場合。ランダムに要素を選択するわけではありません。 IEnumerable/IEnumerable<T>に関する動作は、そのページで明確に定義されています。

予測可能な順序付けの最も重要な例外は、自然に順序付けされていない辞書とセットです。

IEnumerable<T>を反転するには、 Enumerable.Reverse を使用しますが、位置(インデックスやList<T>など)でインデックス付けされたコレクションを逆に繰り返す必要がある場合)その後、Forループを最後から開始して逆方向に使用する方が効率的です。

45
Jon Skeet

次のようなことをする必要があります。

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」を逆方向に実行することはできませんが、それはいくつかの例ではいいことです。

37
SqlRyan

悲しいことに、 For EachのMSDNドキュメント は、反復の順序が重要でない場合(順序付けされていないセットなど)にFor Each構造が明示的に存在することを示しています。残念ながら、For Eachを逆にする概念はありません。順序はとにかく定義されていないからです。

幸運を!

13
Mike

_System.Linq.Enumerable.Reverse_ メソッドを呼び出して、列挙可能なソースの逆順でIEnuemrable(Of TSource)を取得します。

12
Amy B
For Each s As String In myStringList.Reverse
    //' Do stuff here
Next
3
Tonko Boekhoud

フレームワーク4のTestig、コード

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

3
Dave

実行できない理由は、基本的な設計機能として、For Eachが最後の要素なしで、またはまだ未知の最後の要素で列挙可能な要素を反復処理できるためです。

1
reinierpost

あなたがしなければならないことは、あなたが以前持っていたそれぞれのforで配列を作成し、array.reverseを使用して、配列のfor eachを実行することです。完了

乾杯

0
xxxmandoxxx

ループ内で何が起こるかに応じて、.Addの代わりに.InsertAt(object、0)を実行し、逆列挙と同じ結果を生成できます。

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

お役に立てば幸いです

0
Hisham Shaaban

'何でもリストを作成し、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

'逆順リストをステップスルーします

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

'ToolStripItemとMenu.DropDownItemsを必要なものに置き換えます

0
Georg

受け入れられた答えはその理由を説明しますが、別の例を追加するには、キー(SortedList、SortedDictionary、Dictionaryなど)を持つコレクションに対して次のようにします。

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

リバースしようとしているクラスに拡張機能を追加できます

<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
0