array_diff_recursive

ググっても見つからなかったので作ってみた。(所要時間10分)

解決したい問題

<?php
$a = array('a' => 'a',
        'b' => array('b', 'c'));

$b = array('a' => 'a',
        'b' => array('b'));

var_dump(array_diff($a, $b));

残念な結果

array(0) {
}

function

<?php
function array_diff_recursive($a, $b) {
    $result = array();
    foreach ($a as $k => $v) {
        if (array_key_exists($k, $b)) {
            if (is_array($v)) {
                $result[$k] = array_diff_recursive($v, $b[$k]);
            } else {
                if ($v != $b[$k]) {
                    $result[$k] = $v;
                }
            }
        } else {
            $result[$k] = $v;
        }
    }
    return $result;
}

テスト

<?php
$a = array('a' => 'a',
        'b' => array('b', 'c'));

$b = array('a' => 'a',
        'b' => array('b'));

var_dump(array_diff($a, $b));
var_dump(array_diff_recursive($a, $b));

結果

array(0) {
}
array(1) {
  ["b"]=>
  array(1) {
    [1]=>
    string(1) "c"
  }
}

追記

ほぼ同じルーチンが既にありました。(count 0 の扱いが違うだけ)

見ないで作ったのに、そっくりになったのはちょっと感動。

追記2

当初(5分で)作った没バージョン。色々微妙だけど晒してみる。

<?php
function array_diff_recursive($a, $b) {
    $result = array();
    if (is_array($a)) {
        foreach ($a as $k => $v) {
            if (isset($b[$k])) {
                $ret = array_diff_recursive($a[$k], $b[$k]);
                if (count($ret) > 0) {
                    $result[$k] = $ret;
                }
            } else {
                $result[$k] = $a[$k];
            }
        }
    } else {
        if ($a != $b) {
            return $a;
        }
    }
    return $result;
}

これを5分位で改良して、冒頭の array_diff_recursive が出来ました。