How to merge two multi array without duplicates in PHP

I'm trying to merge two Multiple Arrays.

Both arrays have the same item({ "ort": "rom", "lioc": "inrom" }).

    $test_1 =  '
    {
        "hotels" : { 
            "hotel" : [
                { "ort": "rom", "lioc": "inrom" },
                { "ort": "paris", "lioc": "inpsrisd" },
                { "ort": "berlin", "lioc": "inberlin" },
                { "ort": "milano", "lioc": "inmilano" },
                { "ort": "paris", "lioc": "anotherinpsrisd" },
                { "ort": "muc", "lioc": "inmuc" }
            ]
        }
    }
    ';
    $test_2 =  '
    {
        "hotels" : { 
            "hotel" : [
                { "ort": "rom", "lioc": "inrom" },
                { "ort": "beijing", "lioc": "wanda" }
            ]
        }
    }
    ';
    
    $arr_test1 = json_decode($test_1, TRUE);
    $arr_test2 = json_decode($test_2, TRUE);

    var_dump(json_encode(array_merge_recursive($arr_test1, $arr_test2)));
    var_dump(json_encode(array_unique(array_merge($arr_test1,$arr_test2), SORT_REGULAR)));

If I run this code then I get the following results.

result1:
{
    "hotels" : { 
        "hotel" : [
            { "ort": "rom", "lioc": "inrom" },
            { "ort": "paris", "lioc": "inpsrisd" },
            { "ort": "berlin", "lioc": "inberlin" },
            { "ort": "milano", "lioc": "inmilano" },
            { "ort": "paris", "lioc": "anotherinpsrisd" },
            { "ort": "muc", "lioc": "inmuc" },
            {"ort":"rom","lioc":"inrom"},
            {"ort":"beijing","lioc":"wanda"}
        ]
    }
}

result2:
{
    "hotels" : { 
        "hotel" : [
            { "ort": "rom", "lioc": "inrom" },
            { "ort": "beijing", "lioc": "wanda" }
        ]
    }
}

Both are not my expected results.

enter image description here

As you can see in this screenshot { "ort": "rom", "lioc": "inrom" } item is duplicated in result1.

The point is that don't know what is array's keys are and don't know deep of the array.

I'd like to get the merged array without duplicated items like this.

{
    "hotels" : { 
        "hotel" : [
            { "ort": "rom", "lioc": "inrom" },
            { "ort": "paris", "lioc": "inpsrisd" },
            { "ort": "berlin", "lioc": "inberlin" },
            { "ort": "milano", "lioc": "inmilano" },
            { "ort": "paris", "lioc": "anotherinpsrisd" },
            { "ort": "muc", "lioc": "inmuc" },
            { "ort": "beijing", "lioc": "wanda" }
        ]
    }
}

How can I solve this?

Answer

Solution:

array_merge_recursive is actually a very good place to start, but it doesn't allow you to make the inner array unique. This could be achieved by using your own recursive unique implementation. An example of such a function

function recursiveUnique($input): array
{
    // if the input is not an array, just return the input
    if (!is_array($input)) {
        return $input;
    }
    // check if the array is a list or an associative array
    else if (count($input) === 0 || array_keys($input) === range(0, count($input) - 1)) {
        return array_values(array_unique($input, SORT_REGULAR));
    }
    else {
        foreach ($input as $key => $value) {
            $input[$key] = recursiveUnique($value);
        }
        return $input;
    }
}

If you feed the recursively merged array to this function, you should get your desired outcome. You can check the functionality in this 3v4l.

Source