あっぽログ
← 記事一覧に戻る

PHPの配列操作関数を使いこなす:array_map・array_filter・array_reduceで関数型スタイルを実践する

はじめに

PHPで開発をしていると、配列の操作は日常的に登場します。foreachでループを回して処理するコードは誰でも書けますが、array_maparray_filterarray_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(falsenull0""など)な値を除去できます。

<?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

内側から順に読むと:

  1. array_filter:在庫ありの商品を絞り込む
  2. array_map:価格を10%引きに変換する
  3. array_reduce:全価格を合計する

foreachと関数型スタイルの使い分け

観点foreacharray_map/filter/reduce
可読性処理が長いときに明確短い変換・集約に向く
副作用外部変数の変更が容易原則として純粋な変換
デバッグステップ実行しやすいチェーンが深いと追いにくい

どちらが優れているという話ではなく、処理の意図に合わせて使い分けるのがベストです。


まとめ

  • array_map:全要素を変換して新しい配列を作る
  • array_filter:条件を満たす要素だけを残す
  • array_reduce:配列を1つの値(または別の配列)にまとめる

これら3つをマスターするだけで、PHPの配列処理がグッとシンプルになります。最初はforeachで書いてから「これはarray_mapで書けないか?」と問いかける習慣をつけると、自然と使いこなせるようになるでしょう。

← 記事一覧に戻る