したがって、次のようなforループがあります。
for var i = 0; i < results.count ; i += 1 {
if (results[i] < 5) {
results.removeAtIndex(i)
i -= 1
}
}
これは機能していました。しかし、優先Swift 3.0構文に変更したとき:
for var i in 0..<results.count {
if (results[i] < 5) {
results.removeAtIndex(i)
i -= 1
}
}
カウントを再チェックせず、元のresults.count
まで継続するため、配列IOOBE例外が発生します。
どうすれば修正できますか?現在は動作しますが、将来はトラブルに巻き込まれたくありません。
filter
を使用するソリューションは優れたソリューションであり、より多くのSwift-lyですが、for-in
を使用することが依然として望ましい場合、別の方法があります。
var results = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for var i in (0..<results.count).reverse()
{
if (results[i] < 5)
{
results.removeAtIndex(i)
//i -= 1
}
}
print(results)
結果:
[5, 6, 7, 8, 9, 10]
さらに、この行i -= 1
を完全に省略できます。
ループ内のremoveAtIndex
の問題は、配列のインデックスを再作成しないことですin-place。したがって、count
による配列の境界外例外が発生します。更新されていません。
逆方向に走査することにより、境界外の例外を回避できます。
代わりにfilter
を使用できますか?
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let greaterThan5 = numbers.filter{$0 >= 5}
print(greaterThan5)
for
- loopを引き続き使用する場合は、enumerate
を使用してインデックスと要素の両方を列挙できます。
for (index, element) in results.enumerate() {
if (element < 5) {
results.removeAtIndex(index)
}
}
ループで何をしているのかにもよりますが、filter
メソッドの方が良いかもしれません。
ループが進む場合...
for var i in (0..<results.count) where results.indices.contains(i) {
//if the index doesn't exist, the loop will be stopped.
if (results[i] < 5) {
results.removeAtIndex(i)
}
}