今回はPHPのarray_map関数について解説します。
array_map関数は、配列を指定したコールバック関数に渡すことで、各要素を一括で処理させた後に、その要素を含む配列を返します。通常、配列内の要素に処理をする場合はループ処理で1つ1つの要素に対して実行しますが、それがarray_map関数によって一括処理できます。
PHP特有で独特な機能であるため、少しわかりにくい部分もあるかと思いますが、これを使いこなすことによって高度な配列処理が可能になり効果的なプログラム開発に役立つはずです。ぜひしっかり覚えておきましょう。
目次
array_map関数の構文
array_map関数の構文は以下のとおりになります。
1 2 3 4 5 |
配列 = array_map ('コールバック関数', 配列, [...配列] ) function コールバック関数($value){ ... } |
第一引数の「コールバック関数」は関数名を指定します。’ ‘か” “で括ってください。
第二引数はコールバック関数に投げたい配列変数を置きます。カンマで区切ることで複数の配列を引数で渡すことができます。配列
あとはarray_map内で指定した関数を記述すればOKで、そこで処理された後に配列を返します。
array_map関数の基本的な使い方
それでは、array_mapを実際に使ってみましょう。
下の例はarray_mapにcalというコールバック関数を指定し、配列$numを渡しています。返ってきた配列変数$resultをprint_rで出力させています。
1 2 3 4 5 6 7 |
$num = array(1, 2, 3, 4, 5); $result = array_map('cal', $num); print_r($result); function cal($value) { return $value * 2; } |
出力結果はご覧の通り。cal関数で各要素が2倍になって返ってきました。
1 2 3 4 5 6 7 8 |
Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 ) |
array_map関数による配列要素への一括処理
なぜコールバック関数内で一括処理ができるのか
上の例で「あれ?」と不思議に思った方がいるのではないでしょうか。
cal関数内で$valueに対し一括で2を掛けているわけですが、配列にそんなことができたのでしょうか?これが最初に不思議に思う点でありarray_map関数の最大の特徴になります。
次の例はarray_map関数を使わずに配列$numに直接2を掛けてみた例です。しかし、このコードだとエラーが出ます。
1 2 3 4 |
//このコードはエラー $num = array(1, 2, 3, 4, 5); $result = $num * 2; print_r($result); |
これをやりたければループ処理で要素ごと取り出してそれぞれに2を掛けなければなりません。
1 2 3 4 5 6 |
$num = array(1, 2, 3, 4, 5); foreach($num as $i => $value){ $num[$i] = $value * 2; } print_r($num); |
以下の通りの結果を得ました。配列処理は本来であればこのようなやり方が一般的です。
1 2 3 4 5 6 7 8 |
Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 ) |
ところが、array_mapでコールバック関数に渡した先では計算できるわけです。Pythonを知っている方なら「まるでnumpyみたいだ」と思うでしょう。
データ構造を見てみよう
なぜこんなことができるのか。それを知るためにこんなコードを作ってみました。
要所要所でvar_dumpを使ってデータ構造を確認してみたいと思います。まず2行目で配列をコールバック関数に渡す前のデータ構造を出力させてみます。次にコールバック関数の先で渡された$valueを出力させ、最後に返ってきた$resultを出力させてみます。
1 2 3 4 5 6 7 8 9 |
$num = array(1, 2, 3, 4, 5); var_dump($num); //①渡す前に出力 $result = array_map('cal', $num); var_dump($result); //③戻り値を出力 function cal($value) { var_dump($value); //②コールバック関数内で出力 return $value * 2; } |
結果はご覧の通りです。まず最初は配列$numが出力されています。次のコールバック関数内の$valueですが、なんと配列ではないのです。配列内の要素がバラけて出力されました。1つの$valueという変数ですが正体は配列ではない複数のint型の値なのです。その後、配列にまとまって$resultに返ってきました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
array(5) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) } int(1) int(2) int(3) int(4) int(5) array(5) { [0]=> int(2) [1]=> int(4) [2]=> int(6) [3]=> int(8) [4]=> int(10) } |
これはとても面白い仕組みです。コールバック内で配列の要素がバラけるために一括処理が可能になるのです。
複数の配列を渡して一括処理した例
コールバック関数に複数の配列を渡すことも可能です。
以下の例は$num1と$num2の2つの配列を処理する例です。コールバック関数で配列同士を掛け算したものを返しています。
1 2 3 4 5 6 7 8 |
$num1 = array(1, 2, 3, 4, 5); $num2 = array(2, 3, 4, 5, 6); $result = array_map('cal', $num1, $num2); print_r($result); function cal($value1, $value2) { return $value1 * $value2; } |
結果はご覧の通り互いの要素同士を掛け算した結果が出力されました。
1 2 3 4 5 6 7 8 |
Array ( [0] => 2 [1] => 6 [2] => 12 [3] => 20 [4] => 30 ) |
無名関数を使った事例
次にコールバック関数を指定する代わりに関数を直接書く方法です。
以下の例は、第一引数に関数を直接書いています。関数名は書く必要はなくfunction(引数){ … }というふうに記述します。この関数名のない関数を無名関数を呼びます。
1 2 3 |
$num = array(1, 2, 3, 4, 5); $result = array_map(function($value){ return $value * 2; }, $num); print_r($result); |
以下の通り出力されます。簡単な計算をさせる場合は無名関数を使った方がコードがシンプルになります。
1 2 3 4 5 6 7 8 |
Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 ) |
まとめ
いかがでしょうか。今回はPHPでのarray_map関数の使い方について解説しました。
本来はループ処理で1つ1つ要素を取り出しながら処理しなければいけない配列ですが、array_map関数を使うことで一括処理が可能になることがおわかりいただけたかと思います。
この機能を使うことで配列に対して複雑な計算をより少ないコードで実現できます。高度な配列処理が可能になりますのでしっかり覚えておきましょう。