💡 今日の3行まとめ
- 配列内の出現回数を数えるときは
foreachではなくarray_count_values()を使う - 集計結果のキー(項目名)を保ったまま多い順に並べるには
arsort()を組み合わせる - 得票率(%)の計算は
count()で取った全体数とround()でシンプルに求める
1. 今日のお題とゴール
アンケートの回答配列から「どの言語に何票入ったか」を集計し、得票数が多い順(降順)に票数と割合(%)を表示するプログラムを作ります。
- 回答配列
$votesの各項目が何回出現したかをカウントする - 得票数が多い順(降順)に並べ替える
- 全体の回答数に対する割合(小数点第1位まで)を計算して出力する
// 期待する出力例
PHP: 4票 (50%)
TypeScript: 2票 (25%)
Go: 1票 (12.5%)
Python: 1票 (12.5%)
2. ❌ やりがちなNGコード vs ⭕ コピペで動く正解コード
❌ やりがちなNGコードBefore
<?php
$votes = ['PHP', 'TypeScript', 'PHP', 'Go', 'PHP', 'TypeScript', 'Python', 'PHP'];
$counts = [];
foreach ($votes as $lang) {
if (!isset($counts[$lang])) {
$counts[$lang] = 0;
}
$counts[$lang]++;
}
rsort($counts); // キー(言語名)が 0, 1, 2... に消えてしまう!
foreach と isset() で手動カウントするとコードが冗長になり、さらに rsort() で並べ替えると連想配列のキー(言語名)が連番に上書きされて消えてしまいます。
⭕ コピペで動く正解コード(PHP 8.3+)After
<?php
declare(strict_types=1);
$votes = ['PHP', 'TypeScript', 'PHP', 'Go', 'PHP', 'TypeScript', 'Python', 'PHP'];
$total = count($votes);
// 1. 要素ごとの出現回数を1行で集計(['PHP' => 4, 'TypeScript' => 2, ...])
$counts = array_count_values($votes);
// 2. キー(言語名)を維持したまま、値(票数)の多い順にソート
arsort($counts);
// 3. 票数と割合(%)を出力
foreach ($counts as $lang => $count) {
$rate = round(($count / $total) * 100, 1);
echo "{$lang}: {$count}票 ({$rate}%)" . PHP_EOL;
}
3. ここだけ押さえる!3つのポイント
1array_count_values() で出現回数を一発集計
配列を渡すだけで「元の値をキー、出現回数を値」にした連想配列を自動で返してくれます。初期化チェックの if (!isset(...)) を書く必要がなくなります。
2連想配列の降順ソートには arsort() を使う
通常の rsort() はキーをリセットして 0, 1, 2... の添字配列に変えてしまいます。連想配列のキー(言語名)を残したまま値の大きい順に並べるには arsort() を使います。
3数えられるのは「文字列」と「整数」のみ
array_count_values() が集計できるのは文字列(string)と整数(int)の要素だけです。null や配列が混ざっていると警告(Warning)が出るため、事前に入力を絞っておくのが安全です。
4. 1分ミニチャレンジ
🚀 手を動かしてみよう
正解コードの arsort($counts); の1行を、昇順ソートの asort($counts); やキー順ソートの ksort($counts); に書き換えて実行してみましょう。出力される順番がどう変化するか、手元ですぐに確認できます。