PHP の array_reduce [PHP]
PHP に array_reduce という関数が用意されていたので喜び勇んで使ってみたんだけど実に興味深い仕様だったのでここに記しておきたい。
array_reduce は関数型言語でいう reduce か fold に相当する関数だ。例を挙げると、
<?php
function conc($acc, $x) { return $acc . $x; }
echo array_reduce(array("a", "b", "c"), "conc");
?>
この結果は abc となる。
別にコールバック関数名を文字列で与えるのが気持ち悪いとかいう話ではない。
次に、array_reduce は第3引数に初期値を与えることができて、それを与えるとコールバック関数が最初に呼ばれるときの第1引数になる(fold になる)。
ではこれはどうなるだろうか。
<?php
function conc($acc, $x) { return $acc . $x; }
echo array_reduce(array("b", "c"), "conc", "a");
?>
これは 0bc になる。
・・・ 0bc?
実は array_reduce の関数プロトタイプをよく見ると理由が分かる。
mixed array_reduce ( array $input, callback $function [, int $initial] )
第3引数の初期値は何故か型が整数に限られるのだ。だから上記の "a" は暗黙に整数に変換されて 0 となっているようだ。一体何を思ってこんな仕様にしたのだろうか。
この問題は以下のような workaround で回避できる。
<?php
function conc($acc, $x) { return ($acc === 0 ? "a" : $acc) . $x; }
echo array_reduce(array("b", "c"), "conc", 0);
?>
結論: PHP では素直に for/foreach を使って命令的に書きましょう。
5.3でmixedになったようです
by 5.3 (2011-11-11 11:42)