質問: お世話になります。 もろもろ調べたのですが、なかなか納得ができません。 掲題の配列の要素をそれぞれ2倍にする関数ですが 1) array_walkはもとの配列の変数$arrayのままで、function適用後の値(2倍かけた値)が得られ、一方array_mapは $array2に格納して出力しなければfunction適用後の値(2倍かけた値)が得られないのは、walkは破壊的メソッドでmapは非破壊的メソッドであるからという理解であっていますでしょうか? 2)なぜ、コールバック関数の中身が$item= $item*2;とreturn $item*2;と違いが生じるのかがそれぞれの関数の仕様からいまいち理解ができません。なんとなくmapのほうが理解できるのですが、walkはマニュアルを見ると返り値として「成功した場合に TRUE を、失敗した場合に FALSE を返します。」と説明がされています。この違いからくるのでしょうか? 3)2)に関連してですが、そもそも成功と失敗とは何を指しているのでしょうか? 4)2)に関連してですが、このコールバック関数でtrueやfalseを返すことに全く意味がないように思えるのですが。。配列の値やkeyに関数を適用する意図があって作られたwalkやmapであると理解しているのですが、まったくarray_walkの意味がないような気がしてならないのですが、どのようなケースを想定してる関数(これでなくては処理できない?)なのでしょうか? もし具体的な例とかがあれば。。 なにとぞ、宜しくお願い申し上げます。 ``` walk ``` ``` map $array=array(5,10); function twice ($item) { return $item*2; } $array2=array_map('twice',$array); var_dump($array2); ?> ```
回答: array_map、 array_walk > > array_map — 指定した配列の要素にコールバック関数を適用する > > array_walk — 配列の全ての要素にユーザー定義の関数を適用する > > > 違いが全然分からない・・・・これは公式が言葉足らずですね。 引数や戻り値のUsage的なアレを見ればarray_walkは破壊メソッドなのはかろうじてわかりますが・・・・ そもそもmapという名称は地図を連想するかと思いますが、 工場でプレス加工して一度に大量の製品を作る事もmapと呼ばれるそうです。 そこから転じて、配列の中身に同じ処理を加えて加工後の値を一気に取り出す事を指すそうです。 mapは関数型プログラミングのList操作に属するもので、 高階関数 map等のワードでググると関数型プログラミングでは一般的に使用される関数として紹介されています。 特徴は大体こんな感じ * 非破壊メソッドである * 関数を引数として要求する * 戻り値に加工後の配列を返す * 加工前と加工後の配列は要素数は一致する 下記がJavaScriptでの実装の一例です。 PHPのarray_mapとは少し違いますが、Arrayに内蔵されているmapメソッドを利用して実現しています。 ``` var twice = function (it) { return it * 2; }; var arr = [1, 2, 3].map(twice); console.log(arr); // [2, 4, 6] ``` 逆にwalkは何者なんでしょうね? foreachが言語構造として実装されてしまっているので要らない関数にしか見えません。 (一応array_walk_recursiveまでいけば役に立つと思うのですが...) 「追記部分」 レスを読んでいると下記の記事がお役に立ちそうなので、共有します。 array_mapにありがとう、さよなら 部分適用ってなんだ コールバック関数による配列操作はそもそもPHPに必要ありません。 関数型プログラミングをやるにはPHPは不向きだと私は思っています。 foreachという万能言語構造がありますから、やりたいことの大多数は高階関数がなくてもできます。 array_mapとforeach、array_walk等を無理に混ぜると、コードが読みづらくなる可能性は高いです。 コードの見通しを良くする為に関数型プログラミングの書き方で統一するくらいなら、 最初からScalaのような関数型言語を使えば良いじゃないかと考えます。 ChatWorkも最初はPHPで、後に全サービスをScalaで書き直したそうです。 ただし、将来PHPもJavaからスピンオフしたScalaみたいな言語が生まれるかもしれませんね。