for ループで合計を求める
このレッスンで分かること
for (初期化; 条件; 更新)で、配列を先頭から順に処理できます- 集計は「ループの外で用意し、中で更新し、外で返す」形になります
要素が増えるたびに、行を書き足すはめになる
山田 太郎さんの作品には、それぞれ閲覧数が付いています。合計を出したいとき、ここまでの知識ではこう書くしかありません。
JavaScript
const views = [120, 80, 45];
console.log(views[0] + views[1] + views[2]); // => 2453 つならまだ書けます。ですが作品が 20 個になったら views[19] まで並べることになり、しかも作品が 1 つ増えるたびにこの行を書き直すはめになります。要素数が変わっても書き直さずに済む道具が for 文です。
丸カッコの中は 3 つに分かれている
for 文の丸カッコには、セミコロンで区切られた 3 つの式が並びます。
JavaScript
for (初期化; 条件; 更新) {
// くり返したい処理
}| 式 | いつ動くか | 配列を回すときの定番 |
|---|---|---|
| 初期化 | ループが始まる前に 1 回だけ | let i = 0 |
| 条件 | 毎回のくり返しの前に判定 | i < arr.length |
| 更新 | 本体を実行したあと毎回 | i++ |
配列を先頭から末尾まで回す形は、ほぼ固定です。インデックスは 0 から始まるので初期化は let i = 0、最後のインデックスは length - 1 なので条件は i < arr.length になります。
JavaScript
const titles = ["プロフィールサイト", "自己紹介カード", "スキル一覧の表"];
for (let i = 0; i < titles.length; i++) {
console.log(i, titles[i]);
}
// => 0 プロフィールサイト
// => 1 自己紹介カード
// => 2 スキル一覧の表i が 3 になったところで条件 3 < 3 が偽になり、ループを抜けます。動きが読めなくなったら、小さい配列で 1 周ずつ紙に書き出してください。地味ですが最短の解決法です。
iは index の頭文字で、ループの番号として世界中で使われている慣習です。C でも Java でも Python でも同じなので、iを見たら「ループの番号だな」と読めるようになります。
外で用意して、中で更新して、外で返す
くり返して 1 つの答えを組み立てるときの形は決まっています。ためる変数をループの外で用意し、ループの中で更新し、ループを抜けてから返します。
JavaScript
let joined = "";
for (let i = 0; i < titles.length; i++) {
joined += titles[i]; // 中で更新する
}
console.log(joined); // ループを抜けてから使うjoined は中身が変わるので const ではなく let です。そして初期値をどう置くかが要点になります。文字列をつなぐなら空文字、数を足し合わせるなら 0 から始めます。こうしておくと、空の配列を渡されたときにも自然に正しい答えが出ます。要素が 0 個なら条件が最初から偽で本体は 1 度も動かず、初期値がそのまま答えになるからです。
同じくらい大事なのが return を置く場所です。ループの中に書くと 1 周目で関数が終わってしまい、1 件ぶんの結果しか返りません。全部を回し終えたあと、ループの外で返してください。
よくある間違い
- 区切りをカンマにする — 3 つの式はセミコロンで区切ります。カンマで書くと
SyntaxErrorになります - 条件で
<=を使う —i <= titles.lengthにすると、最後に存在しない番号を触ります。数を集計している場合はundefinedを足してNaNになります - 更新を書き忘れて無限ループ —
i++を忘れるとiがずっと0のままで、条件が真であり続けます。ブラウザのタブが固まるので、書いたらまず更新式を確かめてください
要件
- 関数名は
totalViews、引数は数値の配列views1 つ、戻り値は数値 - くり返しには
for文を使うこと (for-ofやreduceではなく、インデックスを使うfor) - 合計用の変数を
0で初期化し、ループの外でreturnすること
入出力例
totalViews([]) → 0
totalViews([120]) → 120
totalViews([120,80,45]) → 245
totalViews([0,0,0]) → 0
totalViews([10,20,30,40]) → 100