break と continue でループを制御する
このレッスンで分かること
breakはループそのものを終わらせますcontinueはその周だけ飛ばして、次の周に進みます
最後まで見なくていいのに、最後まで見ている
ここまでのループは、配列を必ず先頭から末尾まで全部まわしていました。ですが実際のデータには「飛ばしたい要素」と「ここまで来たらもう見なくていい」があります。作品一覧なら、非公開のものは飛ばしたいし、並べるのが 3 件までなら 4 件目以降は見る必要がありません。前者が continue、後者が break です。
| キーワード | 何をするか |
|---|---|
continue | 今の周の残りを飛ばして、次の周へ進む |
break | ループ自体を終わらせる |
どちらも単独では使わず、if と組み合わせて「この条件のときだけ」という形で書きます。条件を付けずに置くと、break は必ず 1 周で終わり、continue は本体が一度も実行されません。
continue は、その周だけを捨てる
JavaScript
const views = [0, 120, 0, 80];
let total = 0;
for (const v of views) {
if (v === 0) {
continue; // 閲覧が無い日は数えない
}
total += v;
}
console.log(total); // 200continue に出会うと、その周の残りの行は実行されず、次の要素に進みます。同じことは if (v !== 0) { ... } でも書けます。処理が 1 行ならそのほうが自然ですが、本体が 10 行あって除外条件が 3 つになると、if で囲む書き方はインデントがどんどん深くなります。除外を先に片付けて continue で抜ければ、本体を浅いまま保てます。
break は、そこでループを終わらせる
JavaScript
const titles = ["プロフィールサイト", "自己紹介カード", "スキル一覧の表"];
for (const title of titles) {
console.log(title);
if (title === "自己紹介カード") {
break; // ここで終わり
}
}
// プロフィールサイト
// 自己紹介カード3 番目は出力されません。探しものが見つかったあとに残りを見ても意味が無い、という場面のための道具です。要素が数万件ある配列なら、break があるかどうかで処理時間がまるで変わります。
気を付けたいのは判定を書く位置です。件数を数えて打ち切るときは、足してから数える。
JavaScript
let count = 0;
for (const title of titles) {
count++;
if (count === 2) {
break;
}
}count++ より前に判定を置くと、2 件目を数える前に抜けてしまい 1 件で終わります。1 行の順番で結果が変わるので、増やしてから数える、と順番ごと覚えてください。
breakはswitchでも使いました。どちらも「いちばん近いブロックを抜ける」という同じ働きです。ループが二重になっているとき、内側のbreakが抜けるのは内側のループだけで、外側は続きます。
よくある間違い
whileの中でcontinueを使う —forの更新式は自動で実行されますが、whileでは更新行を自分で書いています。continueがその行を飛び越すと、条件がいつまでも変わらず止まらなくなりますbreakのつもりでcontinueを書く — 結果は合っていても、最後まで無駄にまわります。飛ばすのか、終わるのか。ここが 2 つの唯一の違いです
要件
- 関数名は
pickPublishedTitles、引数は配列titlesと配列flagsの 2 つ、戻り値は文字列の配列 flags[i]がfalseの要素はcontinueで飛ばすこと- 集めた件数が
3になったらbreakでループを抜けること - 打ち切りの判定は、要素を追加したあとに行うこと
入出力例
pickPublishedTitles([], []) → []
pickPublishedTitles(["プロフィールサイト"], [true]) → ["プロフィールサイト"]
pickPublishedTitles(["下書きメモ","自己紹介カード"], [false,true]) → ["自己紹介カード"]
pickPublishedTitles(["プロフィールサイト","自己紹介カード","スキル一覧の表","ブログ"], [true,true,true,true]) → ["プロフィールサイト","自己紹介カード","スキル一覧の表"]
pickPublishedTitles(["下書きメモ","プロフィールサイト","自己紹介カード","スキル一覧の表","ポートフォリオ"], [false,true,true,true,true]) → ["プロフィールサイト","自己紹介カード","スキル一覧の表"]