for-of で配列を走査する
このレッスンで分かること
for (const item of arr)で、要素そのものを直接受け取れます- 番号が要るときは、これまでどおり
forを選びます
番号を書くから、番号を間違える
前のレッスンで書いた for を思い出してください。丸カッコの中で i の面倒を 3 つも見ているのに、本体で i を使っているのは titles[i] の 1 か所だけでした。やりたいのは「要素を 1 つずつ取り出す」であって、番号そのものには興味がありません。それでも、初期化と条件と更新を正しく書く責任だけは負わされています。
番号に用が無いなら、番号を書かない構文があります。for-of です。
JavaScript
const works = ["プロフィールサイト", "自己紹介カード", "スキル一覧の表"];
for (const work of works) {
console.log(work);
}
// => プロフィールサイト
// => 自己紹介カード
// => スキル一覧の表of の右に配列を、左に「1 周ごとに 1 要素を受け取る変数」を書きます。変数名は自由ですが、works に対して work のように単数形にすると読みやすくなります。受け取る変数は周ごとに新しく作られるので、中身を書き換えないかぎり const で宣言して構いません。むしろ const にしておけば、うっかり書き換えたときにエラーで気付けます。
番号を書かないということは、番号を間違えようが無いということです。- 1 を書き忘れる事故も、<= にして 1 つ多く回す事故も起きません。
番号が要るときは for のまま
判断の基準は 1 つだけです。番号が要るなら for、要らないなら for-of です。
| 項目 | for | for-of |
|---|---|---|
| 受け取るもの | インデックス | 要素そのもの |
| 何周目かが分かるか | 分かる | 分からない |
| 逆順や 1 つ飛ばし | 書ける | 書けない |
| 書き間違えやすさ | 3 つの式ぶんある | ほぼ無い |
「3 番目だけ印を付けたい」「うしろから回したい」という要求があるなら for を選びます。それ以外は for-of のほうが短く、安全です。番号が要らないところをわざわざ番号つきで書いていると、読み手に「なぜ番号が要るのだろう」と考えさせてしまいます。
ためる先をループの中で作ると、最後の 1 件しか残らない
for-of でよくやるのが、1 要素ずつ加工して新しい配列にためる処理です。前のレッスンで覚えた push と組み合わせます。
JavaScript
const views = [120, 80, 45];
const doubled = [];
for (const view of views) {
doubled.push(view * 2);
}
console.log(doubled); // => [240, 160, 90]ためる先の doubled は、ループの外で空配列として用意するのが型です。ループの中で const doubled = []; と書くと毎周からっぽに戻るので、最後の 1 件しか残りません。置く場所を間違えないでください。
この形なら、元の views は書き換わりません。元のデータを残したまま別の形を作れるので、あとで「元の値は何だったのか」が分からなくなる事故を防げます。ためる先を const で宣言してよいのも同じ理由です。push は中身を変えるだけで、doubled に別のものを入れ直しているわけではありません。
よくある間違い
ofをinと書く —for-inが返すのは要素ではなくキー、つまり"0""1"という文字列です
JavaScript
for (const x of works) { console.log(x); } // 作品名が出る
for (const x in works) { console.log(x); } // "0" "1" "2" が出る- 番号が必要なのに
for-ofを選ぶ — 何周目かを知る手段が無いので、自分でカウンタを足すことになります。そこまでするなら、最初からforのほうが素直です
要件
- 関数名は
listWorkTitles、引数は文字列の配列works1 つ、戻り値は文字列の配列 - くり返しには
for-of文を使うこと (インデックスを使うforではなく) - 結果は新しい配列にためて返すこと (
worksそのものを書き換えない)
入出力例
listWorkTitles([]) → []
listWorkTitles(["プロフィールサイト"]) → ["- プロフィールサイト"]
listWorkTitles(["プロフィールサイト","自己紹介カード"]) → ["- プロフィールサイト","- 自己紹介カード"]
listWorkTitles(["プロフィールサイト","自己紹介カード","スキル一覧の表"]) → ["- プロフィールサイト","- 自己紹介カード","- スキル一覧の表"]