# ch07 — 各列の合計を出力

Source: https://php-school.pages.dev/topics/array-multi/ch07-col-sum/
Site: AIと学ぶPHPの学校 (https://php-school.pages.dev)
Lesson: 多次元配列
Level: L2

Reference (official): https://www.php.net/manual/ja/language.types.array.php

## 本文

# ch07 — 各列の合計を出力

## 概要

**各列の合計** を出すのは、行合計 (ch06) より一段難しい。配列は「行 (= 内側配列) の並び」として持っているので、列方向に取り出すには **添字で列番号を固定して全行を走査する** 必要がある。発想を「**外側で列、内側で行**」と入れ子の順を入れ替えるか、または **`$colSum[$j]` のような列ごとの合計を貯める配列を用意して、行を回しながら加算する** ことになる。

典型パターンは後者。`$colSum = [0, 0, 0];` を用意しておき、`foreach ($table as $row) { foreach ($row as $j => $value) { $colSum[$j] += $value; } }` のように **内側 foreach のキー `$j` (列番号)** を使って列ごとの合計を貯める。1 回のループで全列の合計が同時に組み立てられるので効率が良い。

この章では「**全行が同じ列数である**」ことが暗黙の前提になる。行ごとに列数がバラつく (ジャグ配列) と `$colSum[$j]` が未定義になったり、列数の取り方 (`count($table[0])` を「1 行目基準」で取るのが普通) が壊れる。表として扱うなら全行同じ列数、というルールがここで効いてくる。ch11 の CSV パースでもこの前提を守ることで、列ごとの集計がきれいに繋がる。

## 学習目標

- 列ごとに合計値を計算できる
- 「外側で列、内側で行」と入れ子の順を入れ替える発想ができる
- `$colSum[$j]` のような列ごとの合計を貯める配列で組み立てられる
- 全行が同じ列数であることが前提になると理解する

## 所要時間

スライド 4 分 + ドリル 1 問 = **10 分**

## ドリル

| no | 内容 |
|---|---|
| 01 | 3 行 3 列の配列の各列の合計を 3 行で出力 |

## 採点

```bash
php scripts/grade.php topics/array-multi/ch07-col-sum/drill/01-each-col-sum/
```

## 関連チャプター

- [`ch06-row-sum`](../ch06-row-sum/) — 行合計の対の章 (この章の前提)
- [`ch11-csv-to-2d`](../ch11-csv-to-2d/) — CSV を 2 次元配列にして列合計を出す応用
- [`ch12-summary`](../ch12-summary/) — 列合計を「教科ごとのクラス平均」として総合演習で使う

## スライド

---
marp: true
theme: dojo
paginate: true
size: 16:9
---

<!--
LLM_CONTEXT:
  Lesson 6 / Chapter 7
  目的: 2 次元配列の「各列」の合計を計算・出力できるようにする
  扱わない: 連想配列との組み合わせ (ch08 以降)
  読み上げ時間目安: 3 分半〜4 分
-->

# 各列の合計を出す

Lesson 6 / Chapter 7

---

## 行ではなく「列」で合計したい

```php
$table = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
];
```

- 列 0 の合計 = 1 + 4 + 7 = 12
- 列 1 の合計 = 2 + 5 + 8 = 15
- 列 2 の合計 = 3 + 6 + 9 = 18

→ 「外側で列番号 `$j`、内側で行番号 `$i`」と入れ子の順を入れ替える。

---

## for を入れ替えた書き方

```php
<?php
$table = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
];
$cols = count($table[0]);    // 列数 = 3
$rows = count($table);       // 行数 = 3

for ($j = 0; $j < $cols; $j++) {
    $sum = 0;
    for ($i = 0; $i < $rows; $i++) {
        $sum += $table[$i][$j];   // 行 $i、列 $j
    }
    echo $sum . "\n";
}
```

実行結果:

```
12
15
18
```

---

## 添字の順をよく確認

```php
$table[$i][$j]
```

- `$i` = 行番号 (どの行か)
- `$j` = 列番号 (その行の何番目か)

外側を `$j` (列) にしても、配列にアクセスする時は **行→列の順** で書く。
ここを `$table[$j][$i]` と書くと別の場所を読んでしまう。

---

## 全行が同じ列数である前提

```php
$jagged = [
    [1, 2, 3],
    [4, 5],
    [7, 8, 9, 10],
];
```

- 上の例では「列 2 の合計」を出そうとすると、2 行目には列 2 が無くて壊れる
- 「列ごとの合計」を出したいときは、全行の列数が揃っている前提を確認
- 揃っていなければ、まず形を整える (本章では扱わない)

---

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

✅ 列ごとの合計を 1 列 1 行ずつ出力できる
✅ 外側ループ = 列、内側ループ = 行、と順を入れ替えられる
✅ `$table[$i][$j]` の添字の順を間違えない
✅ 全行が同じ列数である前提を意識できる

→ ドリルへ
