ch12 12章中 12章目

ch12 — 多次元配列の総合演習

スライドで見る

この章を AI と学ぶ

💬 AI に聞く質問例 3 件
  1. 「ch12 — 多次元配列の総合演習」のつまずきやすいポイントを、初学者向けに3つ教えてください

    ChatGPT Claude Gemini

  2. 「ch12 — 多次元配列の総合演習」について、自分の手で試せる練習問題を3つ出してください (難易度を上げながら)

    ChatGPT Claude Gemini

  3. 「ch12 — 多次元配列の総合演習」を学んだ後、次に学ぶと良いトピックは何ですか?理由も教えてください

    ChatGPT Claude Gemini

概要

このトピックの最後は 総合演習。お題は典型的な「学生 × 教科の成績データ」で、標準入力から「1 件 = 名前 + 複数の数値」の形式を読み取り、2 次元配列やオブジェクトリストに組み立て、行ごとの平均 (各学生の平均) と列ごとの平均 (教科ごとのクラス平均) を使い分ける ことを目的にする。ここまで (ch01〜ch11) で扱った断片的な技術が、1 つのプログラムとして繋がる経験になる。

ドリル 01 (学生別平均) では 行ごとの集計 が問われる。array_sum($scores) / count($scores) のように 1 件のレコードに対して平均を出すパターンで、ch06 (行合計) の発展形。ドリル 02 (教科別クラス平均) では 列ごとの集計 が問われ、ch07 (列合計) の発想を平均に拡張する。同じデータを「縦に見るか / 横に見るか」で答えが変わる、というデータ集計の核心がここで腹落ちする。

実務でも「売上を月別に見たいのか / 商品別に見たいのか」「ユーザー別の合計か / 日別の合計か」のように 集計軸の切り替え は常に出てくる。この章でその発想を一度通すと、後で BI ツールやデータ集計スクリプトを書く時の発想の元になる。標準入力 → パース → 2 次元配列 → 集計 → 出力 という流れを自分の手で一気通貫に書けるようになるのがゴール。

学習目標

  • 標準入力から「1 件 = 名前 + 複数の数値」のデータを読み、2 次元配列やオブジェクトリストに組み立てられる
  • 行ごとの計算 (各学生の平均) と列ごとの計算 (教科ごとの平均) を 1 つのプログラムで使い分けられる
  • ここまで (ch01〜ch11) を組み合わせて使える

ドリル

no 内容
01 学生 3 人の 3 教科点数を読み、各学生の平均を出力
02 学生 3 人の 3 教科点数を読み、教科ごとのクラス平均を出力

解説スライド 全 7 枚

右の ボタン キー(またはスワイプ)で次のスライドに進めます。 下の「縦表示」を開くと全スライドを一気に読めます。

  1. 多次元配列の総合演習

    Lesson 6 / Chapter 12

  2. 入力データを「表」として持つ

    例として「学生 3 人 × 3 教科の点数」を考える。

    入力例:

    太郎,80,70,90
    花子,60,85,75
    次郎,90,65,80
    • 1 行 = 1 人分のデータ
    • 名前 + 3 教科の点数

    → 「行 = 学生」「列 = 教科」と見れば、ch01〜ch11 でやってきた表と同じ。

  3. オブジェクトリストに組み立てる

    <?php
    $students = [];
    while (($line = fgets(STDIN)) !== false) {
        $line = rtrim($line, "\n");
        if ($line === "") continue;
        $cols = explode(",", $line);
        $students[] = [
            'name' => $cols[0],
            'scores' => [(int)$cols[1], (int)$cols[2], (int)$cols[3]],
        ];
    }
    • 名前は文字列のまま、点数は整数に変換
    • 1 件分を連想配列 (name + scores) にして配列に追加
  4. 各学生の平均 = 行方向の集計

    <?php
    foreach ($students as $s) {
        $avg = array_sum($s['scores']) / count($s['scores']);
        echo $s['name'] . ": " . $avg . "\n";
    }
    • 1 件 (1 行) の中で array_sum / count
    • ch06 (各行の合計) の発展
  5. 教科ごとのクラス平均 = 列方向の集計

    <?php
    $subjects = count($students[0]['scores']);   // 3
    for ($j = 0; $j < $subjects; $j++) {
        $sum = 0;
        foreach ($students as $s) {
            $sum += $s['scores'][$j];
        }
        $avg = $sum / count($students);
        echo $avg . "\n";
    }
    • 外側 = 教科 (列)、内側 = 学生 (行)
    • ch07 (各列の合計) の発展
  6. 集計結果を組み合わせると「成績表」になる

    • 名前 + 平均 → 個人成績
    • 教科ごとの平均 → クラス全体の弱点
    • 両方を組み合わせれば、教科別の偏りや個人の得意分野が見える

    ここまで来れば、簡易的な集計プログラムは多次元配列だけで十分作れる。

  7. このチャプターでできるようになること

    ✅ 入力をオブジェクトリストや 2 次元配列に組み立てられる ✅ 行方向 (各人の平均) と列方向 (各教科のクラス平均) を使い分けられる ✅ ch01〜ch11 を組み合わせて 1 つのプログラムにまとめられる

    → ドリルへ

1 / 7
📜 スライドを全部一気に読む(縦表示)

Lesson 6 / Chapter 12


入力データを「表」として持つ

例として「学生 3 人 × 3 教科の点数」を考える。

入力例:

太郎,80,70,90
花子,60,85,75
次郎,90,65,80
  • 1 行 = 1 人分のデータ
  • 名前 + 3 教科の点数

→ 「行 = 学生」「列 = 教科」と見れば、ch01〜ch11 でやってきた表と同じ。


オブジェクトリストに組み立てる

<?php
$students = [];
while (($line = fgets(STDIN)) !== false) {
    $line = rtrim($line, "\n");
    if ($line === "") continue;
    $cols = explode(",", $line);
    $students[] = [
        'name' => $cols[0],
        'scores' => [(int)$cols[1], (int)$cols[2], (int)$cols[3]],
    ];
}
  • 名前は文字列のまま、点数は整数に変換
  • 1 件分を連想配列 (name + scores) にして配列に追加

各学生の平均 = 行方向の集計

<?php
foreach ($students as $s) {
    $avg = array_sum($s['scores']) / count($s['scores']);
    echo $s['name'] . ": " . $avg . "\n";
}
  • 1 件 (1 行) の中で array_sum / count
  • ch06 (各行の合計) の発展

教科ごとのクラス平均 = 列方向の集計

<?php
$subjects = count($students[0]['scores']);   // 3
for ($j = 0; $j < $subjects; $j++) {
    $sum = 0;
    foreach ($students as $s) {
        $sum += $s['scores'][$j];
    }
    $avg = $sum / count($students);
    echo $avg . "\n";
}
  • 外側 = 教科 (列)、内側 = 学生 (行)
  • ch07 (各列の合計) の発展

集計結果を組み合わせると「成績表」になる

  • 名前 + 平均 → 個人成績
  • 教科ごとの平均 → クラス全体の弱点
  • 両方を組み合わせれば、教科別の偏りや個人の得意分野が見える

ここまで来れば、簡易的な集計プログラムは多次元配列だけで十分作れる。


このチャプターでできるようになること

✅ 入力をオブジェクトリストや 2 次元配列に組み立てられる ✅ 行方向 (各人の平均) と列方向 (各教科のクラス平均) を使い分けられる ✅ ch01〜ch11 を組み合わせて 1 つのプログラムにまとめられる

→ ドリルへ

この章で取り組む 演習問題の流れ (2ステップ)
  1. 01 ドリル 01 — 各学生の平均点を出力 README.md starter.php answer.php
  2. 02 ドリル 02 — 教科ごとのクラス平均を出力 README.md starter.php answer.php

演習問題の詳細

この章の演習問題の内容を読めます。実際に手元で解くには教材リポジトリを clone してください。

ドリル 01 — 各学生の平均点を出力

問題

標準入力で 3 行のデータが与えられます。各行は次の形式です。

名前,国語の点,数学の点,英語の点

入力例:

太郎,80,70,90
花子,60,90,90
次郎,100,100,70

各学生について、3 教科の 平均点 を計算し、次の形で 1 行ずつ出力してください。

名前: 平均

期待される出力:

太郎: 80
花子: 80
次郎: 90

ヒント

  • 1 行ずつ fgets(STDIN) で読み、explode(",", $line) で分割
  • 1 件分を ['name' => ..., 'scores' => [...]] のような連想配列にして配列に追加
  • array_sum($scores) / count($scores) で平均
  • 今回は割り切れる点数になっているので、echo $avg でそのまま整数として表示される

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

ドリル 02 — 教科ごとのクラス平均を出力

問題

標準入力で 3 行のデータが与えられます。各行は次の形式です。

名前,国語の点,数学の点,英語の点

入力例:

太郎,60,80,100
花子,90,80,70
次郎,90,80,100

各教科のクラス平均 (3 人の平均) を計算し、国語 → 数学 → 英語 の順に 1 行ずつ出力してください。

期待される出力:

80
80
90

ヒント

  • 各行を 2 次元配列に組み立てる (名前は無視してよいし、'scores' キーに点数だけ入れてもよい)
  • 外側 = 教科 (列)、内側 = 学生 (行) で for ループ
  • 各教科について $sum += $row[$j]; し、最後に学生数で割る
  • 今回は割り切れる点数になっているので echo $avg でそのまま整数として表示される

🧪 ブラウザで試す

スライドのコードを写経して ▶ 実行、自分で書いて 📝 採点 で答え合わせ。初回のみ PHP ランタイム読込で数秒かかります。

PHP ランタイム未読込

          

        

演習問題(2問)

  1. ドリル 01 — 各学生の平均点を出力

    README.md starter.php answer.php

  2. ドリル 02 — 教科ごとのクラス平均を出力

    README.md starter.php answer.php

サイト内で問題文・雛形・解答例を確認できます。実際に手元で解くには教材リポジトリを clone してください。

完了にすると進捗に反映されます