つくる 作品リストを一覧にする

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部

このレッスンで分かること

  • 配列とループを組み合わせて一覧の文字列を組み立てられます
  • i + 1 を使えばインデックスから 1 始まりの番号を作れます
  • 空配列のときに何を返すかを、自分で決めて書けます

つくる 作品リストを一覧にする とは

第5章で学んだ配列とループを全部使って、作品名の配列から番号付きの一覧文字列を作る関数を書きます。

ここまでで何ができるようになったか

第5章では、複数の値をまとめて扱う方法を身に付けました。振り返っておきましょう。

レッスンできるようになったこと
配列のきほん[] で配列を作り、arr[0]arr.length で中身を扱う
要素を足す・取り除くpush pop shift unshift で中身を変える
for ループで合計を求めるインデックスを使って先頭から順に処理する
for-of で配列を走査する番号を書かずに要素そのものを受け取る
while で条件を満たす間くり返す回数が決まらないくり返しを条件で止める
break と continue要素を飛ばす、途中で抜ける

第4章までは、値をひとつずつ変数に入れて if で分岐するところまででした。そこに配列とループが加わったことで、件数が変わっても書き直さなくていいコードが書けるようになっています。これは「一覧」を扱うすべての画面の土台です。

今回はその総仕上げとして、山田 太郎さんの作品名の配列から、そのまま画面に出せる番号付きの一覧を組み立てます。

buildWorkList(["プロフィールサイト", "自己紹介カード"]); // "1. プロフィールサイト // 2. 自己紹介カード"

組み立ての設計を先に決める

いきなりコードを書く前に、やることを 3 つに分けます。

  1. 空配列だったら、専用のメッセージを返して終わる
  2. 配列を先頭から順にまわし、番号 + ". " + 作品名 の行を作る
  3. 行と行のあいだに改行を入れてつなぎ、できた文字列を返す

この 3 つに分けてしまえば、あとは 1 つずつ書くだけです。難しく見える課題も、日本語で手順に分解してから書くと迷子になりません。

手が止まる原因のほとんどは、コードの書きかたが分からないことではなく、何をすればよいかが決まっていないことです。書く前に日本語で手順を並べる習慣は、この先ずっと効きます。

番号を作る

作品名の配列にはインデックスしか無いので、表示用の番号は自分で作ります。インデックスは 0 から始まり、番号は 1 から始まるので、差はいつも 1 です。

インデックス i表示したい番号
01i + 1
12i + 1
23i + 1

番号が必要なので、ここは for-of ではなく通常の for を選びます。前のレッスンの使い分けがそのまま効いてきます。

const titles = ["プロフィールサイト", "自己紹介カード"]; for (let i = 0; i < titles.length; i++) { console.log((i + 1) + ". " + titles[i]); } // 1. プロフィールサイト // 2. 自己紹介カード

(i + 1) をカッコで囲んでいる点に注目してください。カッコが無いと i + 1 + ". " の順に左から評価され、たまたま今回は同じ結果になりますが、意図を示すためにも囲んでおくのが安全です。

改行でつなぐ

行と行をつなぐ改行は \n と書きます。バックスラッシュと n の 2 文字で 1 つの改行を表します。

ここで気を付けたいのが、改行を入れる場所です。素直に「各行のうしろに \n を足す」と書くと、最後の行のうしろにも改行が付いてしまいます。

let result = ""; for (let i = 0; i < titles.length; i++) { result += (i + 1) + ". " + titles[i] + "\n"; // 末尾に余分な改行が残る }

見た目では気付きにくいのに、文字列を比べるテストでは容赦なく失敗します。回避のしかたは、2 行目以降を書く前に改行を足すことです。

let result = ""; for (let i = 0; i < titles.length; i++) { if (i > 0) { result += "\n"; // 2 行目以降だけ、前に改行を足す } result += (i + 1) + ". " + titles[i]; }

i > 0 という条件がそのまま「2 行目以降」を意味します。1 行目のときだけ改行を足さない、という考えかたです。

区切り文字を要素の「うしろ」ではなく「あいだ」に置く、という考えかたは一覧を組み立てるときの定番です。カンマ区切りでも同じことが起きるので、ここで型として覚えてしまいましょう。

空配列のときを決める

最後に、作品がまだ 1 つも無い場合です。何も考えずに書くと、空文字列 "" が返ります。画面には何も出ず、まるで壊れているように見えます。

そこで、空配列のときは専用のメッセージを返すことにします。判定は関数の先頭でやってしまうのがきれいです。

function buildWorkList(titles) { if (titles.length === 0) { return "作品はまだありません"; } // ここから先は、要素が 1 つ以上あることが保証されている }

先に特殊なケースを片付けておくと、そのあとのコードは「要素がある場合」だけを考えればよくなります。条件分岐が入り組まず、読みやすさが段違いです。

空のとき、ゼロのとき、ひとつだけのとき。この 3 つはプログラムが壊れやすい境界で、テストでも必ず確認されます。今回の課題でもテストに入っているので、忘れずに対応してください。

全体の骨組みを決める

3 つの部品がそろったので、置く順番を決めます。空判定、ためる変数の用意、ループ、最後に返す、の順です。

function buildWorkList(titles) { // 1. 空配列なら専用メッセージを返して終わる // 2. ためる変数を "" で用意する // 3. for でまわし、2 行目以降には先に改行を足してから 1 行ぶんを足す // 4. できあがった文字列を返す }

この 4 行のコメントを先に書いてから、上から順に中身を埋めていくと迷いません。書き終えたらコメントは消しても残しても構いません。

要素が 1 つのときを手で追っておきましょう。i0 のときだけ回り、i > 0 は偽なので改行は入らず、"1. プロフィールサイト" になります。改行の付きかたが心配なときは、この確認がいちばん早いです。

動作を確かめる

書けたら、頭の中ではなく実際に呼び出して確かめましょう。

console.log(buildWorkList([])); console.log(buildWorkList(["プロフィールサイト"])); console.log(buildWorkList(["プロフィールサイト", "自己紹介カード", "スキル一覧の表"]));

3 件のときの出力は、番号が 1 から 3 まで並び、行のあいだにだけ改行が入った形になります。ここまで来れば、あとは作品が何件になっても関数を書き直す必要はありません。第8章で学ぶ DOM と組み合わせれば、この文字列を実際の画面に表示できます。

よくある間違い

  • 末尾に余分な改行が残る — 各行のうしろに \n を足すと最後にも付きます。あいだに入れる書きかたにしましょう
// result += titles[i] + "\n"; // 末尾に余分 if (i > 0) { result += "\n"; } // あいだにだけ入る result += titles[i];
  • 番号がずれるi をそのまま使うと 0 から始まる一覧になります。表示用は i + 1 です
// result += i + ". " + titles[i]; // 0. から始まる result += (i + 1) + ". " + titles[i]; // 1. から始まる
  • ためる変数をループの中で宣言するlet result = "" をループの本体に書くと毎周からっぽに戻り、最後の 1 行しか残りません。宣言はループの前です

要件

  1. 関数名は buildWorkList、引数は文字列の配列 titles 1 つ、戻り値は文字列
  2. 各行は 番号 + ". " + 作品名 の形にすること。番号は 1 から始まる
  3. 行と行のあいだだけを \n でつなぐこと (末尾に余分な改行を付けない)
  4. 空配列のときは "作品はまだありません" を返すこと

入出力例

buildWorkList([])"作品はまだありません" buildWorkList(["プロフィールサイト"])"1. プロフィールサイト" buildWorkList(["プロフィールサイト","自己紹介カード"]) → "1. プロフィールサイト 2. 自己紹介カード" buildWorkList(["プロフィールサイト","自己紹介カード","スキル一覧の表"]) → "1. プロフィールサイト 2. 自己紹介カード 3. スキル一覧の表" buildWorkList(["プロフィールサイト","自己紹介カード","スキル一覧の表","ブログ","ポートフォリオ"]) → "1. プロフィールサイト 2. 自己紹介カード 3. スキル一覧の表 4. ブログ 5. ポートフォリオ"

ヒント

main.js
main.js
学習モード

メモ

つくる 作品リストを一覧にする

⌘S で保存