y_uti のブログ

統計、機械学習、自然言語処理などに興味を持つエンジニアの技術ブログです

複数の配列を取る array_reduce の実装

PHP の array_reduce は一つの配列しか扱えません。array_map などと同じように、複数の配列を扱いたいことがあります。簡単な例を一つ挙げるならベクトルの内積計算です。次のように書きたいところです。

<?php
$vec1 = array(1, 2, 3);
$vec2 = array(4, 5, 6);
$initial = 0;
$result = array_reduce(
    function ($acc, $x, $y) { return $acc + $x * $y; }, $initial, $vec1, $vec2);

そこで、このような私家版 array_reduce を書いてみました。こんな感じでしょうか。

<?php
function my_array_reduce() {
  $args = func_get_args();
  $func = array_shift($args);
  $result = array_shift($args);
  while ($args[0]) {
    $result = call_user_func_array(
        $func,
        array_merge(
            array($result),
            array_map(function (&$a) { return array_shift($a); }, &$args)));
  }
  return $result;
}

while の条件節では、各配列の要素数が異なるときのエラー処理が必要ですね。この部分は面倒なのでサボっています。
array_merge 部分は call_user_func_array に渡すための処理です。array($result) で一要素の配列を作っておいて array_merge するというのは何ともぎこちないです。array_unshift して結果の配列全体を戻してくれる関数があればスマートなのですが。