- Day 29:自力コーディング練習(後半)
- 自力コーディングの基本方針
- 課題①:最大値を求める(自力コーディング用テンプレート)
- 課題②:配列を検索(自力コーディング用テンプレート)
- 課題③:データをフィルター(自力コーディング用テンプレート)
- 課題④:合計を計算(自力コーディング用テンプレート)
- 自力コーディング用ミニチェックリスト
- 自力コーディング練習用テンプレート(ブラウザで実行しながら確認)
- Day 29 後半のまとめ
- Day 30:最初の総合制作(後半)
- 商品管理システムの土台設計
- 商品一覧表示:すべての商品を見やすく出す
- 商品追加:新しい商品をシステムに登録する
- 商品検索:商品名で探す
- 価格フィルター:指定価格以下の商品だけを表示する
- 合計金額計算:商品価格の合計を求める
- 商品管理システム 総合テンプレート(ブラウザで実行可能)
- Day 30 後半のまとめ
Day 29:自力コーディング練習(後半)
「“見本なし”で書けるようになるための、実戦トレーニング」
Day 29後半では、前半で確認した
- 最大値を求める
- 配列を検索
- データをフィルター
- 合計を計算
という4つの課題を、本当に見本なしで書けるようになるための練習方法 を整理していきます。
ここでの主役は「コード」ではなく、 “どうやって自分の頭の中で組み立てるか” という思考プロセスです。
自力コーディングの基本方針
「いきなり書かない。まず“言葉”で組み立てる」
ステップ1:紙やメモに“日本語で”手順を書く
いきなりコードを書こうとすると、 文法やスペルに意識が取られて、肝心の「処理の流れ」がぼやけてしまいます。
そこで、まずは 日本語で手順を書く ことをおすすめします。
例:最大値を求める場合
- 配列が空なら「最大値なし」とする
- 最初の要素を「仮の最大値」とする
- 2番目以降の要素を順番に見ていく
- 今の値が仮の最大値より大きければ、仮の最大値を更新する
- 最後まで見終わったときの仮の最大値が答え
この「日本語の手順」が、 そのまま for文・if文・変数更新 に変換されていきます。
ステップ2:日本語の手順を“コードの骨組み”に変える
次に、その手順をコードの骨組みにします。
例:最大値の骨組み
function findMax(numbers) {
// 1. 配列が空なら「最大値なし」
// 2. 最初の要素を仮の最大値
// 3. 2番目以降を順番に見る
// 4. 大きければ更新
// 5. 最後に仮の最大値を返す
}
JavaScriptこのように、コメントだけ先に書いておく と、 「何を書くべきか」がはっきりした状態でコードを書けます。
課題①:最大値を求める(自力コーディング用テンプレート)
思考ステップをコメントにしてから埋める
// 数値配列の最大値を求める関数(自力コーディング練習用)
function findMax(numbers) {
// 1. 配列が空かどうかをチェックする
// → 空ならnullを返す
// 2. 最初の要素を「仮の最大値」として変数に入れる
// 3. 2番目以降の要素をfor文で順番に見る
// 4. 今の値が仮の最大値より大きければ、仮の最大値を更新する
// 5. 最後に仮の最大値を返す
}
JavaScriptこのテンプレートを使って、 コメントをヒントにしながら、自分で中身を埋める 練習をすると効果的です。
課題②:配列を検索(自力コーディング用テンプレート)
「最初に見つかった1件」を返す検索
// 配列から特定の値を検索する関数(自力コーディング練習用)
function findValueInArray(array, target) {
// 1. 配列を先頭から順番にfor文で回す
// 2. 各要素がtargetと一致するかどうかをif文で判定する
// 3. 一致したら、その値をreturnで返す
// 4. 最後まで見ても見つからなかった場合はnullを返す
}
JavaScriptここでも、 「for → if → return → 最後にnull」 という流れを、 頭の中でなぞりながら書いていきます。
課題③:データをフィルター(自力コーディング用テンプレート)
条件に合うものだけを新しい配列に集める
// 数値配列から、指定した値以上のものだけを集める関数(自力コーディング練習用)
function filterGreaterOrEqual(numbers, threshold) {
// 1. 結果を入れるための空の配列resultを用意する
// 2. 元の配列numbersをfor文で先頭から順番に回す
// 3. 各要素valueがthreshold以上かどうかをif文で判定する
// 4. 条件に合う場合はresultにpushする
// 5. ループが終わったらresultを返す
}
JavaScriptフィルターは、
- 「空の配列を用意する」
- 「条件に合うものだけpushする」
という2点をセットで覚えておくと、 どんな条件にも応用しやすくなります。
課題④:合計を計算(自力コーディング用テンプレート)
「蓄積」の基本パターンを体に染み込ませる
// 数値配列の合計を計算する関数(自力コーディング練習用)
function calculateSum(numbers) {
// 1. 合計を入れる変数sumを0で初期化する
// 2. 配列numbersをfor文で先頭から順番に回す
// 3. 各要素valueをsumに足していく(sum += value)
// 4. ループが終わったらsumを返す
}
JavaScriptこの「sumを0からスタートして足し込んでいく」パターンは、 平均値・スコア集計・売上合計など、 あらゆる場面で使われる重要な型です。
自力コーディング用ミニチェックリスト
「書き終わったあとに、自分で見直すポイント」
チェック1:関数の“入り口”と“出口”がはっきりしているか
- 引数は何を受け取る前提になっているか
- 戻り値は何を返す前提になっているか
- 「見つからない」「空配列」のときの扱いを決めているか
チェック2:ループの範囲が正しいか
for (let i = 0; i < array.length; i++)のiの初期値と条件は正しいか- 1番目から回すのか、2番目から回すのかを意識できているか
チェック3:条件式が意図通りか
>=と>を間違えていないか===と==を意図して使っているか
チェック4:元の配列を壊していないか
- フィルターや合計では、元の配列を書き換えていないか
- 新しい配列や変数に結果を入れているか
自力コーディング練習用テンプレート(ブラウザで実行しながら確認)
最後に、 「自分で書いたコードを差し替えて試せる」ための シンプルなテンプレートを用意しておきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Day 29 後半:自力コーディング練習 用テンプレート</title>
</head>
<body>
<h1>Day 29 後半:自力コーディング練習</h1>
<p>ブラウザのコンソールを開いて、ログを確認してください。</p>
<script>
console.log('--- 自力コーディング練習開始 ---');
// ここに自分で書いた関数を貼り付けて試していきます。
// 例:findMax / findValueInArray / filterGreaterOrEqual / calculateSum など
// サンプルデータ
const numbers = [3, 10, 5, 8, 2];
const numbers2 = [50, 120, 80, 200, 150];
const numbers3 = [100, 200, 50];
const fruits = ['apple', 'banana', 'orange'];
// ここから下は、自分で書いた関数を呼び出してテストする場所です。
// 例:
// console.log('最大値:', findMax(numbers));
// console.log('検索結果:', findValueInArray(fruits, 'banana'));
// console.log('フィルター結果:', filterGreaterOrEqual(numbers2, 100));
// console.log('合計:', calculateSum(numbers3));
console.log('--- 自力コーディング練習テンプレートの実行が完了しました ---');
</script>
</body>
</html>
このテンプレートの中に、 自分で書いた関数をコピペして動かしてみる ことで、
- うまく動いたときの「できた!」という感覚
- うまく動かなかったときの「どこが違うんだろう?」という気づき
を積み重ねていくことができます。
Day 29 後半のまとめ
Day 29後半では、
- いきなりコードを書かず、まず「日本語で手順を書く」こと
- コメントを“骨組み”として先に書き、そのあと中身を埋める練習方法
- 最大値・検索・フィルター・合計という4つの課題を、 自力で書くためのテンプレートとチェックポイント
を整理しました。
自力コーディングは、 「悩む時間」そのものが成長の時間 です。
見本を閉じて、 少し不安なまま手を動かしてみる—— その一歩を何度も踏むことで、 「自分の書き方」「自分の癖」「自分の得意パターン」が 少しずつ育っていきます。
Day 30以降も、この「自力で組み立てる感覚」を軸にしながら、 より実践的なコードへ進んでいくことになりますので、 ぜひ今日の練習を何度か繰り返して、 自分の中に“書ける感覚”を定着させていってください。
Day 30:最初の総合制作(後半)
「小さな“商品管理システム”を完成させる」
Day 30後半では、これまで学んだ
- 配列・オブジェクト
- 検索・フィルター・ソート・合計
- 関数による部品化
を総動員して、商品管理システム を1つの形にまとめていきます。 ここではコンソール上で動く「ミニ商品管理アプリ」を作りながら、
- 商品追加
- 商品一覧
- 商品検索
- 価格フィルター
- 合計金額計算
を、1つの“まとまった仕組み”として組み立てていきます。
商品管理システムの土台設計
商品データの構造を決める
まずは「商品1件」をどのような形で表現するかを決めます。
// 1件の商品データの例
const product = {
id: 1, // 商品を一意に識別するID
name: 'ノート', // 商品名
price: 100, // 価格(数値)
};
JavaScriptid:商品を識別するための番号name:商品名price:価格(数値)
商品一覧を配列で管理する
複数の商品をまとめて管理するために、配列を使います。
// 商品一覧(商品管理システムの“データベース”的な役割)
const products = [
{ id: 1, name: 'ノート', price: 100 },
{ id: 2, name: 'ボールペン', price: 150 },
{ id: 3, name: '消しゴム', price: 80 },
];
JavaScriptこの products 配列が、 商品管理システムの「中心となるデータ」です。
商品一覧表示:すべての商品を見やすく出す
1件の商品を表示する関数
まずは、1件の商品を見やすく表示する関数を作ります。
// 1件の商品を表示する関数
function printProduct(product) {
console.log(`ID: ${product.id}/商品名: ${product.name}/価格: ${product.price}円`);
}
JavaScript商品一覧を表示する関数
次に、配列 products を受け取って、全件を表示する関数を作ります。
// 商品一覧を表示する関数
function printProductList(products) {
console.log('--- 商品一覧 ---');
for (const product of products) {
printProduct(product); // 1件ずつ表示
}
console.log('--- 商品一覧ここまで ---');
}
// 実行例
printProductList(products);
JavaScript- この関数は、後で「検索結果」「価格フィルター結果」を表示するときにも再利用します。
- 「一覧表示」は、どんな管理システムでも必ず登場する基本機能です。
商品追加:新しい商品をシステムに登録する
追加前に簡単なチェックをする
商品追加では、最低限次のようなチェックを意識します。
idが数値であることnameが空文字でないことpriceが0以上の数値であること- 同じ
idの商品が既に存在しないこと
// 新しい商品が妥当かどうかをざっくりチェックする関数
function validateNewProduct(newProduct) {
if (typeof newProduct.id !== 'number' || Number.isNaN(newProduct.id)) {
return { valid: false, message: 'IDが不正です。数値を指定してください。' };
}
if (typeof newProduct.name !== 'string' || newProduct.name.trim() === '') {
return { valid: false, message: '商品名が不正です。空でない文字列を指定してください。' };
}
if (typeof newProduct.price !== 'number' || Number.isNaN(newProduct.price) || newProduct.price < 0) {
return { valid: false, message: '価格が不正です。0以上の数値を指定してください。' };
}
return { valid: true, message: 'OK' };
}
JavaScript商品追加関数を作る
// 新しい商品を追加する関数(バリデーション付き)
function addProduct(products, newProduct) {
// 妥当性チェック
const result = validateNewProduct(newProduct);
if (!result.valid) {
console.log('商品追加に失敗しました:' + result.message);
return false;
}
// IDの重複チェック
const exists = products.some(product => product.id === newProduct.id);
if (exists) {
console.log('商品追加に失敗しました:同じIDの商品が既に存在します。');
return false;
}
// 問題なければ追加
products.push(newProduct);
console.log('商品を追加しました:', newProduct);
return true;
}
// 実行例
const newProduct = { id: 4, name: 'シャープペンシル', price: 300 };
addProduct(products, newProduct);
printProductList(products);
JavaScript- バリデーションと重複チェックを入れることで、「おかしな商品」が登録されるのを防ぎます。
- 実務のシステムでも、このようなチェックは非常に重要です。
商品検索:商品名で探す
部分一致で検索する関数
商品検索では、商品名にキーワードが含まれているかどうかで判定します。
// 商品名にキーワードが含まれている商品を検索する関数
function searchProductsByName(products, keyword) {
if (typeof keyword !== 'string') {
return [];
}
const trimmed = keyword.trim();
if (trimmed === '') {
return [];
}
const lowerKeyword = trimmed.toLowerCase();
const result = [];
for (const product of products) {
const lowerName = product.name.toLowerCase();
if (lowerName.includes(lowerKeyword)) {
result.push(product);
}
}
return result;
}
JavaScript検索結果を表示する関数
function printSearchResult(products, keyword) {
console.log(`--- 商品検索(キーワード: "${keyword}") ---`);
const result = searchProductsByName(products, keyword);
if (result.length === 0) {
console.log('該当する商品は見つかりませんでした。');
console.log('キーワードを変えて再度お試しください。');
} else {
printProductList(result);
}
console.log('--- 商品検索ここまで ---');
}
// 実行例
printSearchResult(products, 'ペン');
printSearchResult(products, 'ノート');
printSearchResult(products, '鉛筆'); // ヒットなし
JavaScript- キーワードが空文字や不正な型の場合は、結果0件としています。
- 大文字・小文字を区別しない検索にすることで、使い勝手がよくなります。
価格フィルター:指定価格以下の商品だけを表示する
フィルター関数を作る
// 指定価格以下の商品だけを抽出する関数
function filterProductsByMaxPrice(products, maxPrice) {
if (typeof maxPrice !== 'number' || Number.isNaN(maxPrice) || maxPrice < 0) {
return [];
}
const result = [];
for (const product of products) {
if (typeof product.price !== 'number' || Number.isNaN(product.price)) {
// 価格情報が不正な商品はスキップ
continue;
}
if (product.price <= maxPrice) {
result.push(product);
}
}
return result;
}
JavaScriptフィルター結果を表示する関数
function printFilteredByMaxPrice(products, maxPrice) {
console.log(`--- ${maxPrice}円以下の商品 ---`);
const result = filterProductsByMaxPrice(products, maxPrice);
if (result.length === 0) {
console.log('条件に合う商品は見つかりませんでした。');
console.log('価格の条件やデータを確認してください。');
} else {
printProductList(result);
}
console.log('--- 指定価格以下の商品表示ここまで ---');
}
// 実行例
printFilteredByMaxPrice(products, 150);
printFilteredByMaxPrice(products, -100); // 不正値 → 0件
JavaScript- 「条件に合うものだけを新しい配列に集める」というフィルターの基本パターンを使っています。
- 不正な価格や不正な入力値に対しても、安全に動作するようにしています。
合計金額計算:商品価格の合計を求める
合計関数を作る
// 商品配列の合計金額を計算する関数
function calculateTotalPrice(products) {
let total = 0;
for (const product of products) {
if (typeof product.price !== 'number' || Number.isNaN(product.price)) {
// 価格が不正な商品はスキップ
continue;
}
total += product.price;
}
return total;
}
JavaScript合計金額を表示する関数
function printTotalPrice(products, label = '対象商品') {
const total = calculateTotalPrice(products);
console.log(`${label}の合計金額は ${total} 円です。`);
}
// 実行例:全商品の合計
printTotalPrice(products, '全商品');
// 実行例:150円以下商品の合計
const filtered = filterProductsByMaxPrice(products, 150);
printTotalPrice(filtered, '150円以下の商品');
JavaScript- 合計は「蓄積」の基本パターンです。
- フィルター結果にも同じ関数を使い回せるようにしている点が重要です。
商品管理システム 総合テンプレート(ブラウザで実行可能)
以下は、Day 30後半の内容を1つにまとめた「商品管理システム」のテンプレートです。 ブラウザで開き、コンソールを見ながら動きを確認できるようになっています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Day 30 後半:商品管理システム 総合テンプレート</title>
</head>
<body>
<h1>Day 30 後半:最初の総合制作 - 商品管理システム</h1>
<p>ブラウザのコンソールを開いて、ログを確認してください。</p>
<script>
console.log('--- 商品管理システム開始 ---');
// 商品データの配列(初期データ)
const products = [
{ id: 1, name: 'ノート', price: 100 },
{ id: 2, name: 'ボールペン', price: 150 },
{ id: 3, name: '消しゴム', price: 80 },
];
// 1件の商品を表示する関数
function printProduct(product) {
console.log(`ID: ${product.id}/商品名: ${product.name}/価格: ${product.price}円`);
}
// 商品一覧を表示する関数
function printProductList(products) {
console.log('--- 商品一覧 ---');
for (const product of products) {
printProduct(product);
}
console.log('--- 商品一覧ここまで ---');
}
// 新しい商品が妥当かどうかをチェックする関数
function validateNewProduct(newProduct) {
if (typeof newProduct.id !== 'number' || Number.isNaN(newProduct.id)) {
return { valid: false, message: 'IDが不正です。数値を指定してください。' };
}
if (typeof newProduct.name !== 'string' || newProduct.name.trim() === '') {
return { valid: false, message: '商品名が不正です。空でない文字列を指定してください。' };
}
if (typeof newProduct.price !== 'number' || Number.isNaN(newProduct.price) || newProduct.price < 0) {
return { valid: false, message: '価格が不正です。0以上の数値を指定してください。' };
}
return { valid: true, message: 'OK' };
}
// 商品追加関数
function addProduct(products, newProduct) {
const result = validateNewProduct(newProduct);
if (!result.valid) {
console.log('商品追加に失敗しました:' + result.message);
return false;
}
const exists = products.some(product => product.id === newProduct.id);
if (exists) {
console.log('商品追加に失敗しました:同じIDの商品が既に存在します。');
return false;
}
products.push(newProduct);
console.log('商品を追加しました:', newProduct);
return true;
}
// 商品検索関数
function searchProductsByName(products, keyword) {
if (typeof keyword !== 'string') {
return [];
}
const trimmed = keyword.trim();
if (trimmed === '') {
return [];
}
const lowerKeyword = trimmed.toLowerCase();
const result = [];
for (const product of products) {
const lowerName = product.name.toLowerCase();
if (lowerName.includes(lowerKeyword)) {
result.push(product);
}
}
return result;
}
function printSearchResult(products, keyword) {
console.log(`--- 商品検索(キーワード: "${keyword}") ---`);
const result = searchProductsByName(products, keyword);
if (result.length === 0) {
console.log('該当する商品は見つかりませんでした。');
console.log('キーワードを変えて再度お試しください。');
} else {
printProductList(result);
}
console.log('--- 商品検索ここまで ---');
}
// 価格フィルター関数
function filterProductsByMaxPrice(products, maxPrice) {
if (typeof maxPrice !== 'number' || Number.isNaN(maxPrice) || maxPrice < 0) {
return [];
}
const result = [];
for (const product of products) {
if (typeof product.price !== 'number' || Number.isNaN(product.price)) {
continue;
}
if (product.price <= maxPrice) {
result.push(product);
}
}
return result;
}
function printFilteredByMaxPrice(products, maxPrice) {
console.log(`--- ${maxPrice}円以下の商品 ---`);
const result = filterProductsByMaxPrice(products, maxPrice);
if (result.length === 0) {
console.log('条件に合う商品は見つかりませんでした。');
console.log('価格の条件やデータを確認してください。');
} else {
printProductList(result);
}
console.log('--- 指定価格以下の商品表示ここまで ---');
}
// 合計金額計算関数
function calculateTotalPrice(products) {
let total = 0;
for (const product of products) {
if (typeof product.price !== 'number' || Number.isNaN(product.price)) {
continue;
}
total += product.price;
}
return total;
}
function printTotalPrice(products, label = '対象商品') {
const total = calculateTotalPrice(products);
console.log(`${label}の合計金額は ${total} 円です。`);
}
// --- 動作確認 ---
console.log('初期状態の商品一覧:');
printProductList(products);
console.log('商品を追加します:');
const newProduct = { id: 4, name: 'シャープペンシル', price: 300 };
addProduct(products, newProduct);
printProductList(products);
console.log('商品検索のテスト:');
printSearchResult(products, 'ペン');
printSearchResult(products, 'ノート');
printSearchResult(products, '鉛筆');
console.log('価格フィルターのテスト:');
printFilteredByMaxPrice(products, 150);
printFilteredByMaxPrice(products, -100);
console.log('合計金額計算のテスト:');
printTotalPrice(products, '全商品');
const filtered = filterProductsByMaxPrice(products, 150);
printTotalPrice(filtered, '150円以下の商品');
console.log('--- 商品管理システムの動作確認が完了しました ---');
</script>
</body>
</html>
Day 30 後半のまとめ
Day 30後半では、
- 商品追加・一覧・検索・価格フィルター・合計金額計算を 1つの「商品管理システム」としてまとめたこと
- バリデーションや重複チェックを入れることで、 データの信頼性を守る感覚を持ったこと
- 同じ表示関数・合計関数を、 検索結果やフィルター結果にも再利用する「部品化」の考え方を確認したこと
を整理しました。
ここまで来ると、 「小さくても、ちゃんと役に立つアプリ」を自分の手で作れる状態 に近づいています。
この商品管理システムは、 ユーザー管理・タスク管理・在庫管理など、 さまざまな分野に応用できる“型”になっていますので、 ぜひ自分なりに項目を増やしたり、 画面を付けてみたりしながら、 「自分のプロダクト」として育てていってください。
