• ベストアンサー

カウンタの値が変動するループ。

ループの中で条件によってカウンタの元となる配列の項目を削除したいと 思っています。 具体的には list As List(Of string) For i As Integer = 0 To list.Count - 1 '条件によって、Listの項目を削除 If 条件 list.RemoveAt(i) End If Next 以上のようにすると、Listの項目が減っていくわけですが、iの値は 考慮していないので、いつかエラーが発生します。 カウンタの元となる値が変動した場合、再度その変動した値で最初から ループしなおすようにできないものでしょうか? (For以外のループを使えばいけるのかな…?) アドバイス宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • don_cha
  • ベストアンサー率34% (139/407)
回答No.1

先頭からのループではなく、後尾からのループにすれば大丈夫です。 For i As Integer = list.Count - 1 to 0 step -1 '条件によって、Listの項目を削除 If 条件 list.RemoveAt(i) End If Next

ginfix
質問者

お礼

回答ありがとうございます。 構造体の配列の中身を二次元配列にうつしているんですが、 その時にうまく動かないようです。 list As List(Of structure()) structureの中身はEatchでまわして、Listの中に全部 つっこんでいます。 ご教授いただいた方法で消していくと、項目が複数ある時、 最後の1つが残ってしまうようで…。

その他の回答 (2)

  • don_cha
  • ベストアンサー率34% (139/407)
回答No.3

>構造体の配列の中身を二次元配列にうつしているんですが、 >その時にうまく動かないようです。 >項目が複数ある時、最後の1つが残ってしまうようで…。 配列データの生成は、インデックス番号を0(Zero)始まりにされているのでしょうか?VBの場合任意のインデックス番号をベースに設定が出来てしまうため、場合によっては1始まりや、最終インデックスがCount値と同じと言うこともありえます。 先に答えました内容は配列のインデックスは、先頭が0(Zero)始まりの最大がCount-1としています。 また、条件で一致した際の処理自体に問題が無いかも検証する必要があると思います。

回答No.2

'メモ。その他の例 Option Explicit On Option Strict On Option Compare Binary Option Infer Off Imports System.Collections.Generic Imports System.Diagnostics Class Q4828662 Shared Sub Main() 'Collection InitializerなんてものはVB.NETにはないらしい。 '質問者さんの案。変数iはサブルーチン全体で有効なものだから '二重定義しないように気にする必要があるかも。 Dim x1 As List(Of Integer) = New List(Of Integer) x1.AddRange(New Integer(){1,2,3,4}) Dim i As Integer = 0 Do While i < x1.Count If x1(i) Mod 2 = 1 Then x1.RemoveAt(i) Else i = i + 1 End If Loop Debug.WriteLine("第一テスト") For Each j As Integer in x1 Debug.WriteLine(j) Next '---------------- '何番目に何が削除されるか,という情報が必要な場合。 'あらかじめ別なリストに取り分けておく。 '変数x2はサブルーチン全体で有効な変数。 x1.Clear() x1.AddRange(New Integer(){1,2,3,4}) Dim x2 As List(Of Integer) = New List(Of Integer)() For Each j As Integer in x1 If j Mod 2 = 1 Then x2.Add(j) End If Next For Each j As Integer In x2 x1.Remove(j) Next Debug.WriteLine("第ニテスト") For Each j As Integer in x1 Debug.WriteLine(j) Next '------------------ '今回の例のように,順番は必要ないので,定義する変数を減らしてみたい場合。 x1.Clear() x1.AddRange(New Integer(){1,2,3,4}) 'VB.NETには匿名メソッドもない? x1.RemoveAll(AddressOf Q4828662.MyTest) Debug.WriteLine("第三テスト") For Each j As Integer in x1 Debug.WriteLine(j) Next '----------------- System.Console.ReadKey(true) End Sub Public Shared Function MyTest(x As Integer) As Boolean Return (x Mod 2 = 1) End Function End Class

関連するQ&A