プログラミングを書く時に重要な繰り返し処理(ループ処理)の for について説明します。
何かの処理を行う時に、10行程度の処理を書いたとして、それを10回行いたいときに、10行をコピーして10回貼り付けて100行の処理にして実行させる。ということをして動かすこともできますが、コピペは楽だからそうしたいのかもしれませんが、普通はしません。
10行書いて、それを囲って「10回ループしろ」という命令を与えます。12行程度になるかもしれません。そのとき使うのが「forループ」です。
プログラミング業界は先頭をゼロから数えることが多い。
ところで、プログラミングの業界では最初の要素の位置(インデックス)を、ゼロ、から始めるというが、多くの場合で使われています。
例えば文字列"ABC"があったとして、Aは0番目、Bは1番目、Cは2番目という数え方をします。
普通の社会とうか、日常世界では 0番目 なんて数え方は変で、Aは1番目 Bは2番目として数えると思いますが、プログラミングの業界では 先頭のものは、0番 として数えるのが通例なのです。これはもうなれてくれとしかいえない感じなのです。
「俺は1から始めるんだ!」として1から始めるようにプログラムを書くこともできるとは思うのですが、いろいろ不便になると思いますよ。
コンピュータの黎明期というか、以前のものでは、例えばExcelで使われているVBAというプログラミング言語では、いくつかの場面で、1から始まる番号付けのものも使われています。Excelの行番号が1行目じゃなくて 0行目だったら、変ですよね。なので、1から始まるようになっているのですがそれにともなってExcelのVBAでも1から始まる処理を書く場面はあります。ありますが、いまいち使いにくい感じとして扱われています。
0か1か、どちらかをスタートにするということで、多くの開発者が選択してきたのは、0スタートに落ち着いてきた、という感じです。だいたいのプログラムの場面では 先頭項目が 0 として扱われていて、それが業界の標準になってきているようなので、なれたら楽だと思います。
ということで、今回のループ処理でも、先頭はゼロから開始するということになります。
ループ処理のサンプルコード
forのサンプルを示します。for にはいくつかの書き方があるのでなれておきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
const count = function() { return 5 }; // [1-1] for (let i = 0; i <= 4; i += 1) { console.log(i); } // [1-2] for (let i = 0; i <= count() - 1; i += 1) { console.log(i); } // [2-1] for (let i = 0; i < 5; i += 1) { console.log(i); } // [2-2] for (let i = 0; i < count(); i += 1) { console.log(i); } // [3-1] for (let i = 0, imax = 4; i <= imax; i += 1) { console.log(i); } // [3-2] for (let i = 0, imax = count() - 1; i <= imax; i += 1) { console.log(i); } // [4-1] for (let i = 0, ilen = 5; i < ilen; i += 1) { console.log(i); } // [4-2] for (let i = 0, ilen = count(); i < ilen; i += 1) { console.log(i); } |
ここのコードでは、全て「0 1 2 3 4」と 5行で表示されます。
for文は、forの後のカッコ内が3つの部分にセミコロンで区切られる構文になっていて、「for(最初に実行される部分 ; ループが有効な条件式; ループごとに動作する部分) {ループで実行される部分}」となります。
ループの回数が、固定値(マジックナンバー)として指定することも多くはなく何らかの個数(count)や、長さ(Length)で表されるので、関数として count というのを用意してみました。
[1-1][1-2] の書き方は、最もわかりやすそうです。位置(インデックス)を示す 変数 i が 0 から 4 まで変化して、console.log を 5回 呼び出します。
[2-1][2-2] の書き方は、ループの条件が[1]の「i <= 4」と比較して「i < 5」となり異なっていますが同じことを示していますね。4以下と5未満、とは、iが整数として動くなら同じことです。
[3-1][3-2] の書き方は、少し変わっていますが セミコロン「;」で区切られた先頭部分は、カンマ「,」で区切られていて、i の値と imax が代入されています。
なぜこんな書き方をするのかというと、プログラムで高速さを求める場合に、count を読み出す時にそれなりに時間がかかる処理が行われるときに、[1-2]のように条件式を「i <= count() -1」というように書いてしまうと、ループごとにcountを求める処理に時間がかかってしまって、ループが遅くなるという問題があるからです。iMaxはiの最大値の意味です。
[4-1][4-2] の書き方も [3]とほぼ同様です。ilenというのは、iのlength(長さ)を表しています。
私の場合は統一的に自分のプログラムの中では[3-2]あるいは[1-1]の書き方をするようにしています。
i += 1
加算(インクリメント)代入演算子については、以前の記事で書いていますので、こちらを参考にしてください。
逆順の場合
いくつかの書き方を考えられますが、こんな書き方がよいでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const count = function() { return 5 }; for (let i = 4; 0 <= i; i -= 1) { console.log(i); } // 4 3 2 1 0 と表示される for (let i = count() - 1; 0 <= i; i -= 1) { console.log(i); } // 4 3 2 1 0 と表示される |
for ループを飛ばしたい場合「continue」を使う
ループ中に特定の条件のときだけ処理を書くようにするには、次のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// [1] // 2 4 6 8 10 と表示される for (let i = 1; i <= 10; i += 1) { if ((i % 2) === 0) { // 2の倍数のときだけ処理をする console.log(i); } } // [2] // 2 4 6 8 10 と表示される for (let i = 1; i <= 10; i += 1) { if ((i % 2) !== 0) { continue; // 2の倍数ではなければループを飛ばす } console.log(i); } |
[1]は普通にその処理の場合だけ、if の中に書いています。同じ処理を[2]のように、continue を使って実現することができます。
forループ中に特定の条件になれば「continue」を使ってループを飛ばす処理を書くことができます。
for ループを途中で終わらせたい場合「break」を使う
ある条件になったときに、for ループを終わらせるときは「break」を使います。サンプルはこうなります。
1 2 3 4 5 6 7 8 |
// 1 2 3 4 5 for (let i = 1; i <= 10; i += 1) { console.log(i); if ((i % 5) === 0) { break; // 5の倍数だったらループを止める。 } } |
ループしている最中にある条件になれば、ループを終わるという処理を書くことができます。
まとめ
◇まとめ
ということで、for ループ のいくつかのパターンを紹介しました。
いろいろな書き方がありますが、ループの開始の値と終了の値がループ指定のところに入る書き方がより読みやすいです。
また、逆順の場合の for の書き方もありました。
そして、continue、break という命令でループ処理をコントロールすることができます。
これで、普通のループはうまくつかいこなせると思います。
近いうちに「for (... of ...)」「for (... in ...)」「forEach」などについて、紹介していきます。