Swift 3.0 で C言語スタイルの for ループが廃止されるので、その書き換え方法のまとめ

## C言語スタイル for ループの廃止
<img width="633" alt="Screen Shot 2016-04-08 at 11.55.56 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/65634/43f22d89-fa88-395c-8a56-612167bb9ae0.png">

C言語スタイルの for ループが Swift 3.0 で廃止される見込みの為<font color="silver">(エラーメッセージには将来のみたいな表現だけど)</font>、これまでこのスタイルで書いてきた for ループを書き直さないといけなくなりました。そこで、典型的なパターンを書き直す方法をまとめてみました。

## for var i = 0 ; i < 100 ; i++

もっとも典型的な C言語スタイルの for ループ、0 から 100 未満の for ループの場合です。

```.swift
// C-Style for statement
for var i = 0 ; i < 100 ; i++ {
	print("\(i)")
}
```

```.swift
// Swift 3.0 ready
(0 ..< 100).forEach { print("\($0)") }
```

```.swift
// Swift 3.0 ready
for i in (0 ..< 100) {
	print("\(i)")
}
```

## for var i = 99 ; i >= 0 ; i--

典型的な降順の場合です。

```.swift
// C-Style for statement
for var i = 99 ; i >= 0 ; i-- {
	print("\(i)")
}
```

`reverse()` を使います。

```.swift
// Swift 3.0 ready
(0 ..< 100).reverse().forEach { print("\($0)") }
```

```.swift
// Swift 3.0 ready
for i in (0 ..< 100).reverse() {
	print("\(i)")
}
```

## for var i = 0 ; i < 100 ; i += 2

飛び石になる場合です。

```.swift
// C-Style for statement
for var i = 0; i < 100 ; i += 2 {
	print("\(i)")
}
```

`stride` を使います。`to` の他に `through` もあります。

```.swift
// Swift 3.0 ready
0.stride(to: 100, by: 2).forEach { print("\($0)") }
```

> #### `stride(to:by:)` と `stride(through:by:)` の違い
>
> 誤解しそうですが昇順の場合は、 `to` は「未満」、`through` は「以下」を意味するようです。以下の例を参考にしてください。
>
>```.swift
>0.stride(to: 20, by: 5) // 0, 5, 10, 15
>```
>
>```.swift
>0.stride(through: 20, by: 5) // 0, 5, 10, 15, 20
>```

## for var i = 98 ; i >= 0 ; i -= 2

飛び石で降順の場合です。

```.swift
// C-Style for statement
for var i = 98 ; i >= 0 ; i -= 2 {
	print("\(i)")
}
```

```.swift
// Swift 3.0 ready
98.stride(through: 0, by: -2).forEach { print("\($0)") }
```

こんな書き方もありですね。<font color="silver">EDIT¹</font>

```.swift
// Swift 3.0 ready
0.stride(to: 100, by: 2).reverse().forEach { print("\($0)") }
```

```.swift
// Swift 3.0 ready
for i in 0.stride(to: 100, by: 2).reverse() {
	print("\(i)")
}
```

<font color="silver">EDIT¹:</font> ~~昇順だと `0.stride(to: 100, by: 2)` とかの表現が、降順だと ストレートに表現できず、解釈の入ったようなコードにならざるをえないような気がします。~~<font color="silver">良さそうなアイディアがあればコメントくだされば幸いです。</font>

## 次の再初期化式の指定がなく、刻みが不定の場合

あまり良い例が思いつきませんが、例えば二乗した値が奇数か偶数かで、加算する値が変わる場合を例にしてみます。（例自体には深い意味はありません）

```.swift
// C-Style for statement
for var i = 0 ; i < 100 ; {
	print("\(i)")
	if (i * i) % 2 == 0 { i += 1 }
	else { i += 2 }
}
```

while ループに置き換えるのが良さそうです。

```.swift
// Swift 3.0 ready
var i = 0
while i < 100 {
	print("\(i)")
	if (i * i) % 2 == 0 { i += 1 }
	else { i += 2 }
}
```

## for ループから条件によって抜け出す場合がある場合

あまり良い例が思いつかないのですが、サイコロを振るように乱数を発生させて、特定の数が出たらループを終わらせる事にしてみましょう。

```.swift
// C-Style for statement
for var i = 0 ; i < 100 ; i++ {
	print("\(i)")
	if arc4random_uniform(10) == 0 { break }
}
```

残念ながら、`forEach {}` では `break` 文で for ループを抜ける事は出来ません。そこで、 `for`-`in` 文を使います。

```.swift
// error: forEach で break は使えない
(0 ..< 100).forEach {
	print("\(i)")
	if arc4random_uniform(10) == 0 { break } // error
}
```

```.swift
// Swift 3.0 ready
for i in 0 ..< 100 {
	print("\(i)")
	if arc4random_uniform(10) == 0 { break } // OK
}
```

`continue` を使う場合も `forEach` は使えないので、同様に `for`-`in` に書き換える必要があります。

## 浮動小数点数 など 整数 でない場合 <font color="silver">EDIT²</font>

CGFloat や Double なども `Strideable` なので同様に書くことができます。

```.swift
CGFloat(0).stride(to: 100, by: 1.5).forEach { print("\($0)") }
```

```.swift
0.0.stride(to: 100.0, by: 1.5).forEach { print("\($0)") }
```

## あとがき

<font color="silver">EDIT¹: 例を追加しました。</font>
<font color="silver">EDIT²: 項目を追加しました。</font>

Swift3.0の正式リリース時にはきっと、Apple は「素晴らしいCode のコンバージョンツールを用意する」的な発言をするかと思いますが、この変換を自動的に行えるとは正直思えません。そのかわり、次のバージョンでの変更点などが warning で表示されるのは、時間ができた時に少しづつ移行させる方法は大変合理的だと思います。

それではみなさん、Have a happy coding!!

```.console
Swift Version:
Apple Swift version 2.2 (swiftlang-703.0.18.1 clang-703.0.29)
```