LoginSignup
2
1

More than 5 years have passed since last update.

階層構造を持つ配列のマージ

Last updated at Posted at 2017-09-05

環境

PHP7

やりたかったこと

階層のある配列どうしをマージしたかった。

$a = [
    'a' => 1,
    'b' => [
        'c' => 2,
        'd' => [
            'e' => 3,
            'f' => [
            ]
        ]
    ]
];

$b = [
    'b' => [
        'c' => 6,
        'd' => [
            'f' => [
                'g' => 4
            ]
        ]
    ]
];
function merge_function($a,$b)
{
    // なにがしかの処理
}
print_r(merge_function($a,$b));

期待される結果

php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => 6
            [d] => Array
                (
                    [e] => 3
                    [f] => Array
                        (
                            [g] => 4
                        )
                )
        )
)

↑要は、既にある要素は上書き、ない要素は追加を各階層ごとに行うって感じです。

過去記事もちょっと探してみたものの、それらしいことをやっている記事が見つかりませんでした。余り需要がないってことでしょうか。

やってみたこと

1)array_merge

function merge_function($a,$b)
{
    return array_merge($a,$b);
}
print_r(merge_function($a,$b));

結果↓

php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => 6
            [d] => Array
                (
                    [f] => Array
                        (
                            [g] => 4
                        )
                )
        )
)

第3階層がダメですね。

2)array_merge_recursive

function merge_function($a,$b)
{
    return array_merge_recursive($a,$b);
}
print_r(merge_function($a,$b));

結果↓

php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => Array
                (
                    [0] => 2
                    [1] => 6
                )

            [d] => Array
                (
                    [e] => 3
                    [f] => Array
                        (
                            [g] => 4
                        )
                )
        )
)

第2階層のcが配列に変化してしまってます。

3)配列結合演算子(+)

function merge_function($a,$b)
{
    return $a + $b;
}
print_r(merge_function($a,$b));

結果↓

php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => 2
            [d] => Array
                (
                    [e] => 3
                    [f] => Array
                        (
                        )
                )
        )
)

c、gが上書きできていません。

4)関数で自作

php
function merge_left(array $a,array $b)
{
    $merged_keys = [];
    foreach($a as $k => $v){
        if (isset($b[$k])){
            if (is_array($a[$k]) && is_array($b[$k])){
                $a[$k] = merge_left($a[$k],$b[$k]);
            }
            else{
                $a[$k] = $b[$k];
            }
            $merged_keys[] = $k;
        }
    }
    foreach($b as $k => $v){
        if (!in_array($k,$merged_keys,true)){
            $a[$k] = $b[$k];
        }
    }
    return $a;
}
function merge_function($a,$b)
{
    return merge_left($a,$b);
}
print_r(merge_function($a,$b));

結果↓

php
Array
(
    [a] => 1
    [b] => Array
        (
            [c] => 6
            [d] => Array
                (
                    [e] => 3
                    [f] => Array
                        (
                            [g] => 4
                        )
                )
        )
)

バグがありそうだけど、なんとなく良さそう!

思ったこと

  • do not trust PHP standard functions! Read PHP Manual carefully!
  • in_arrayは罠
  • もっといいやり方があったらコメントが欲しいです・・・(・ε・。)マジデ ありました!感謝!
2
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1