💡 今日の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); に書き換えて実行してみましょう。出力される順番がどう変化するか、手元ですぐに確認できます。