ど素人から毛を生やす。<延>

2つのオブジェクト入り2次元配列が同一か調べたかったし差分を抽出したかった話。

Web > PHP 2025年12月26日(最終更新:0日前)

どもです。
2つの、オブジェクト入り2次元配列が同一か調べたい。あと配列1にあって配列2にない要素を抽出したい。

配列の同一チェック、差分抜き出しは、通常の配列であればarray_diff_assoc()を使うのが定石です。

$a1 = [
    (object)[
        'label' => 'label1',
        'value' => 'aaaaa'
    ]
];

$a2 = [
    (object)[
        'label' => 'label2',
        'value' => 'BBBBB'
    ]
];

print_r(array_diff_assoc($a1, $a2));
//結果:Uncaught Error: Object of class stdClass could not be converted to string

array_diff_assoc()は、配列の中身がオブジェクトだと使えないようです。

foreach($a1 as $k => $a){ $a1[$k] = (array)$a; }
foreach($a2 as $k => $a){ $a2[$k] = (array)$a; }

print_r(array_diff_assoc($a1, $a2));
//結果:Array ( )

配列に変換してみました。array_diff_assoc()は多次元配列の下位層までは比較してくれない模様。

$a1 = [
    (object)[
        'label' => 'label1',
        'value' => 'aaaaa'
    ]
];

$a2 = [
    (object)[
        'label' => 'label2',
        'value' => 'BBBBB'
    ]
];

$a3 = [
    (object)[
        'label' => 'label1',
        'value' => 'aaaaa'
    ]
];

var_dump($a1 == $a2);
//結果:bool(false)

var_dump($a1 == $a3);
//結果:bool(true)

2つの配列が同じものかを調べたい場合、一次元でも多次元でも単純に==で比較するのが正解のようです。
まじかー。

しかし、等号による比較だと「配列1にあって配列2にない要素を抽出」は行えません。

$a1 = [
    (object)[
        'label' => 'label1',
        'value' => 'aaaaa'
    ],
    (object)[
        'label' => 'label2',
        'value' => 'bbbbb'
    ],
];

$a2 = [
    (object)[
        'label' => 'label1',
        'value' => 'aaaaa'
    ],
    (object)[
        'label' => 'label2',
        'value' => 'BBBBB'
    ],
];

foreach($a1 as $k => $a){
    if(in_array($a, $a2)) unset($a1[$k]);
}

print_r($a1);
/* 結果:Array(
    [1] => stdClass Object
        (
            [label] => label2
            [value] => bbbbb
        )
)
*/

in_array()がオブジェクトの比較に対応しているため、array_diff()っぽい動きまでならこれだけで実装できるのでした。

in_array()の第3引数を付けると話が変わってくるので留意。

この記事は役に立ちましたか?
  • _(:3」∠)_ 面白かった (0)
  • (・∀・) 参考になった (0)
  • (`・ω・´) 役に立った (0)