for文によるループと配列の組み合わせを学ぶステージです。配列に入っているひとつひとつの要素(オブジェクト)に対して同じ処理をさせることができます。全く同じ処理というだけでなく、要素毎の違い活用した処理ができるのが強みです。
例えばこのステージでは、0〜5番目の各列に宝石とスイッチを配置します。今までのやり方だと、こんな風になります。
1 2 3 4 5 6 7 8 9 10 |
world.place(Gem(),atColumn:1, row:1) world.place(Switch(),atColumn:1, row:1) world.place(Gem(),atColumn:2, row:1) world.place(Switch(),atColumn:2, row:1) world.place(Gem(),atColumn:3, row:1) world.place(Switch(),atColumn:3, row:1) world.place(Gem(),atColumn:4, row:1) world.place(Switch(),atColumn:4, row:1) world.place(Gem(),atColumn:5, row:1) world.place(Switch(),atColumn:5, row:1) |
ほぼ同じパターンが5回繰り返されますが、残念ながらatColumn:パラメーターが違うので単純なfor文ループにはできません。
まさにこんな時に、配列を使った繰り返しが役に立ちます。
同じforで始まりますが、
1 2 3 |
for (ループ内での変数名) in (配列名) { (ループさせたい処理) } |
のように書きます。これで「(配列名)の中にある要素ひとつひとつを(ループ内での変数名)に入れつつ、(ループさせたい処理)を実行」という意味になります。
正解例のコードを見てみましょう。
1 2 3 4 5 6 7 8 9 10 |
//columnsという配列に0〜5の6つの整数(Int)値を入れておく。 let columns = [0, 1, 2, 3, 4, 5] // Give your loop variable a name and pass in your array. for column in columns { // Place a gem and a switch for each column. // (各列に宝石とスイッチを配置) world.place(Gem(), atColumn: column, row: 1) world.place(Switch(), atColumn: column, row: 1) } |
columns配列の中身が前から1つずつ取り出され、columnという変数に入れられてループ内の処理が行われます。1ループ目はcolumnの中身は0です。なので、world.placeメソッドの中のatColumn:パラメーターには0と書いたのと同じことになります。
そして最初のループが終わって繰り返される時、columnには2番目の値の1がセットされます。つまり2回目のループではatColumn:は1になります。以下、atColumn:が2,3,4,5と変化しながら繰り返されていきます。最終的に全ての陸地にスイッチと宝石が並んでいることでしょう。
このように、ちょっとずつ違う処理を繰り返す時に、その違う部分を変数に置き換えておき、このfor〜in文で毎回変数の中身を変えてやる方法が利用できます。
いつもありがとうございます。
大変勉強になります。
配列1では
var rows = [ ~ ]
配列2では
let columns = [ ~ ]
となっていて
「var」と「let」が違うのは、何故ですか?
詳しくは「Swift var let 違い」とかググってもらうと解説がたくさんあると思いますが、簡単に書くと
letは作られるのは定数といい「一度中身を入れると二度と入れ替えが効かない箱」です。
varは変数で「何度も入れ替えができる箱」という違いです。
一見すると変数の方が便利じゃん、と思うかも知れません。実際Playgroundで作るような小規模なプログラムだととりあえずvarで統一してもあまり実害はないですが、複雑で見通しが悪いプログラムを書くようになってくると、プログラムの最後まで絶対変わらないもの、変わってほしくないものを格納するときはletで作っておけばロックされるということなので、あとでうっかり書き換えてしまってバグになる危険を減らすことができます。「書き換えられない」ことは不便なのではなく、意識して使うメリットもあるということです。
今Playgroundの当該問題ページを見ずにこのコメントを書いてるので、ご指摘のvarとletがどこにあるかわかっておらず、それぞれ適切かどうかの解説はできないですが、その観点で見直すと納得できそうでしょうか?
正直私が書いているコード例ではあまりそこまで深く考えないでvarにしてるところもあるかも知れません(笑)。