4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Cスタイルのfor文をSwift3で書き換えるときにハマるパターン

Last updated at Posted at 2016-11-20

Swift3より前に書いたCスタイルのfor文
for 初期設定; 実行条件; インクリメント
をSwift3以降で
for i in 範囲
に変換するときにハマるパターンがあります。

入れ物がいくつかある。
左からいくつかは丸が入っている。
Base.png
残りの入れ物に三角を入れる処理を行いたい。
Umed.png
丸が入っている最終の入れ物のindexをcurrentPosとし、
最後の入れ物のindexをendPosとする。
Umed With String.png
三角を入れる処理のfor文は、Cスタイルの書き方では

for var i = currentPos + 1; i<=endPos; i += 1 {
	//ポジションiに三角を入れる処理
} 

と書ける。
この書き方を範囲指定の書き方に置き換えると

for i in (currentPos + 1)...endPos {
	//ポジションiに三角を入れる処理
}

となる。

ところが次のように初めから全ての入れ物に丸が入っていた場合、上の範囲指定の書き方ではうまくいかない。
Full.png
この場合、範囲 (currentPos + 1)...endPos5...4 となって実行時エラーになる。範囲の指定は...方式でも..<方式でも、右より左の方が大きいと実行時エラーで落ちる。

Cスタイルの書き方では初期設定と実行条件を与えれば、あとは自動でうまくやってくれますが、Swiftでは範囲の生成がうまく出来ないと実行時エラーになってしまうので注意。

対策は
stride(from: , through: , by: )
を使うことです。throughの値よりもfromの値の方が大きい場合でも、何も実行せずに次の命令に移るだけなのでCスタイルで書くのと同じノリでいけます。
例に上げたやり方だと初期値は1大きいだけなので
(currentPos + 1)..<(endPos + 1)
でも対応できます。

また、dropFirst()を使う方法もあります。

for i in (0...endPos).dropFirst(currentPos + 1) {
}

で可能です。(コメントで指摘してもらったやり方)

Cスタイルのfor文をナウい形に書き換える際は、注意しておきたい。

4
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?