はじめに
PHPで開発をしていると、配列の操作は日常的に登場します。foreachでループを回して処理するコードは誰でも書けますが、array_map・array_filter・array_reduceを使いこなすと、コードが短くなり、意図が明確になります。
この記事では、PHPの代表的な配列操作関数を具体的なコード例とともに紹介します。
array_map:配列の各要素を変換する
array_mapは、配列の全要素に対してコールバック関数を適用し、変換後の新しい配列を返します。
基本的な使い方
<?php
$numbers = [1, 2, 3, 4, 5];
$doubled = array_map(fn($n) => $n * 2, $numbers);
print_r($doubled);
// [2, 4, 6, 8, 10]
アロー関数(fn())と組み合わせると1行でスッキリ書けます。
複数の配列を同時に処理する
<?php
$prices = [100, 200, 300];
$quantities = [2, 5, 1];
$totals = array_map(fn($p, $q) => $p * $q, $prices, $quantities);
print_r($totals);
// [200, 1000, 300]
複数の配列を渡すと、対応するインデックスの要素を同時に処理できます。
array_filter:条件に合う要素だけ残す
array_filterは、コールバック関数がtrueを返す要素だけを残した配列を返します。
基本的な使い方
<?php
$scores = [45, 72, 88, 30, 95, 60];
$passed = array_filter($scores, fn($s) => $s >= 60);
print_r($passed);
// [1 => 72, 2 => 88, 4 => 95, 5 => 60]
注意:
array_filterはキーを保持します。インデックスをリセットしたい場合はarray_values()を使いましょう。
<?php
$passed = array_values(array_filter($scores, fn($s) => $s >= 60));
print_r($passed);
// [0 => 72, 1 => 88, 2 => 95, 3 => 60]
コールバックなしで使う
引数なしで呼び出すと、falsy(false・null・0・""など)な値を除去できます。
<?php
$items = ['apple', '', null, 'banana', 0, 'cherry'];
$cleaned = array_values(array_filter($items));
print_r($cleaned);
// ['apple', 'banana', 'cherry']
array_reduce:配列を1つの値に集約する
array_reduceは、配列の要素を順番に処理しながら1つの値にまとめます。第2引数にコールバック、第3引数に初期値を渡します。
合計を求める
<?php
$numbers = [1, 2, 3, 4, 5];
$sum = array_reduce($numbers, fn($carry, $item) => $carry + $item, 0);
echo $sum; // 15
$carry:前回の処理結果(初回は初期値)$item:現在処理中の要素
連想配列を構築する
array_reduceは合計や最大値だけでなく、配列を作るのにも使えます。
<?php
$users = [
['id' => 1, 'name' => 'Alice'],
['id' => 2, 'name' => 'Bob'],
['id' => 3, 'name' => 'Charlie'],
];
$indexed = array_reduce($users, function ($carry, $user) {
$carry[$user['id']] = $user['name'];
return $carry;
}, []);
print_r($indexed);
// [1 => 'Alice', 2 => 'Bob', 3 => 'Charlie']
3つの関数を組み合わせる
実務では、これらの関数をチェーンして使うことが多いです。
<?php
$products = [
['name' => 'Apple', 'price' => 120, 'inStock' => true],
['name' => 'Banana', 'price' => 80, 'inStock' => false],
['name' => 'Cherry', 'price' => 200, 'inStock' => true],
['name' => 'Grape', 'price' => 350, 'inStock' => true],
];
// 在庫ありの商品だけ抽出 → 価格を10%引きに → 合計金額を計算
$total = array_reduce(
array_map(
fn($p) => $p['price'] * 0.9,
array_filter($products, fn($p) => $p['inStock'])
),
fn($carry, $price) => $carry + $price,
0
);
echo $total; // (120 + 200 + 350) * 0.9 = 594
内側から順に読むと:
array_filter:在庫ありの商品を絞り込むarray_map:価格を10%引きに変換するarray_reduce:全価格を合計する
foreachと関数型スタイルの使い分け
| 観点 | foreach | array_map/filter/reduce |
|---|---|---|
| 可読性 | 処理が長いときに明確 | 短い変換・集約に向く |
| 副作用 | 外部変数の変更が容易 | 原則として純粋な変換 |
| デバッグ | ステップ実行しやすい | チェーンが深いと追いにくい |
どちらが優れているという話ではなく、処理の意図に合わせて使い分けるのがベストです。
まとめ
array_map:全要素を変換して新しい配列を作るarray_filter:条件を満たす要素だけを残すarray_reduce:配列を1つの値(または別の配列)にまとめる
これら3つをマスターするだけで、PHPの配列処理がグッとシンプルになります。最初はforeachで書いてから「これはarray_mapで書けないか?」と問いかける習慣をつけると、自然と使いこなせるようになるでしょう。