Menu

PHPのarray_map():配列のすべての要素に関数を適用する

array_map($callback, $array)は、すべての要素に対してコールバックを呼び出し、結果を新しい配列で返します。アロー関数、キー、複数の配列を同時に処理する方法、array_walkやforeachのほうが向いている場面を学びます。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

array_map($callback, $array)は、$arrayのすべての要素に対して$callbackを呼び出し、結果を新しい配列で返します。コールバックが先、配列が後で、元の配列は変わりません。

fn($p) => $p * 1.2はアロー関数で、1つの式の結果を返す関数です。代わりにどんなcallableでも使えます。

組み込み関数をコールバックに使う

組み込み関数の名前を文字列で渡します。配列全体をきれいにするいちばん短い方法で、すべての値をtrimしたり、文字列を整数に変換したり、大文字小文字を変えたりできます。

array_map('intval', ...)は、フォームやexplode()から来た文字列を本物の整数にする定番の方法です。PHP 8.1のファーストクラスcallable構文でintval(...)と書くこともでき、エディターが補完やチェックをしてくれます。

外側の変数を使うクロージャ

アロー関数は周りの変数を自動で参照できます。従来のfunctionでは、useで取り込む必要があります。どちらも無名関数のページで説明しています。

キー付きのarray_map

配列が1つなら、array_mapは文字列キーも含めてキーを保ちます。ただし、コールバックが受け取るのは値だけです。キーも取得するには、array_keys($array)を2つ目の配列として渡します。すると、コールバックは各配列から1つずつ要素を受け取って呼ばれます。

2つ目の結果に注目してください。複数の配列を渡したとたん、キーは0, 1, 2に置き換わります。最後の行でarray_combine()を使ってキーを作り直しているのはそのためです。

複数の配列を同時に処理する

追加した配列はそれぞれコールバックの追加の引数になり、位置で対応づけられます。配列の長さが違うと、短いほうはnullで埋められます。

コールバックにnullを渡すと関数を呼ばず、配列をペアにまとめます。

array_map、array_walk、foreachの違い

array_mapは新しい配列を作ります。array_walkは渡した配列を参照を通して変更し、コールバックの2つ目の引数としてキーを渡します。foreachはどちらもでき、要素を飛ばしたりbreakで早めに止めたりもできます。

すべての要素がちょうど1つの新しい要素になるならarray_mapを使います。一部の要素を取り除く必要もあるなら、array_filterと組み合わせるか、foreachを書きます。

よくあるミス:引数の順番

array_mapはコールバックが先で配列が後です。隣のarray_filterは逆の順番なので、混同しやすくなっています。

array_map($callback, $array);     // callback first
array_filter($array, $callback);  // array first

入れ替えると、普通の配列は正しいコールバックではないので、PHP 8はTypeErrorを投げます。

PHPは次のように止まります。

PHP Fatal error:  Uncaught TypeError: array_map(): Argument #1 ($callback) must be a valid callback or null, array callback must have exactly two members in /home/index.php:4

2つの引数を入れ替え直せば、ブロックは動きます。

よくある質問

PHPのarray_mapは何をしますか?

配列のすべての要素に対して関数を呼び出し、結果を新しい配列で返します:array_map(fn($n) => $n * 2, [1, 2, 3])は[2, 4, 6]を返します。元の配列は変わりません。

array_mapはキーを保ちますか?

配列が1つなら保ちます。文字列キーも整数キーもそのままです。配列が2つ以上なら、結果には常に新しいキー0, 1, 2...が振られます。

array_mapのコールバックの中でキーを取得するには?

キーを2つ目の配列として渡します:array_map(fn($k, $v) => "$k=$v", array_keys($arr), $arr)。結果はリストになるので、元のキーが必要ならarray_combine(array_keys($arr), ...)で包みます。

array_mapはforeachより速いですか?

意味のある差はありません。どちらも配列を1回ループし、要素ごとの関数呼び出しがない分、素のforeachのほうが少し速いことがよくあります。新しい配列を作る1つの変換のように、読みやすくなるときにarray_mapを選びましょう。

array_mapとarray_walkの違いは何ですか?

array_mapは新しい配列を返し、入力はそのままにします。array_walkはtrueを返し、参照の引数を通して配列をその場で変更するためのものです:array_walk($arr, function (&$v, $k) { $v = trim($v); });。

Coddyのプログラミング言語のイラスト

Coddyでコードを学ぼう

始める