Skip to content
Advertisement

Merge two multidimensional arrays using recursion, but not on full data set

I’m trying to add 2 array data to each other with array_merge(). It’s just attached to the back. But lower levels are ignored.

Is there an alternative to array_merge() that will merge the user values without duolicating the color values?

Existing array data:

$existingtArr = [
    "A" => [
        "color" => 'red',
        "user" => [
            "Daniel" => ["01:18:08", "04:10:12"],
            "Max" => ["01:04:00"],
            "Serto" => ["02:00:02"],
        ]
    ],
    "B" => [
        "color" => 'blue',
        "user" => [
            "Franz" => ["08:40:52"],
            "Hugo" => ["07:08:58"],
        ]
    ]
];

New array data:

$newArr = [
    "A" => [
        "color" => 'red',
        "user" => [
            "Fabian" => ["06:03:00"], // + 1 user
            "Max" => ["04:10:12"], // + 1 new time 
            "Serto" => ["02:00:02"],
        ]
    ],
    "B" => [
        "color" => 'blue',
        "user" => [
            "Franz" => ["08:40:52", "14:05:32", "20:34:15"], // an older one is available, + 2 new times
            "Hugo" => ["04:10:12"], // + 1 time
        ]
    ],
    "C" => [ // + new whole group
        "color" => 'green',
        "user" => [
            "Maxi" => ["07:08:58", "04:10:12"],
        ]
    ]
];

Supplement the existing data with the new data:

echo '<pre>';
print_r(array_merge($existingtArr, $newArr));
echo '</pre>';

Expected result array data:

$resultArr = [
    "A" => [
        "color" => 'red',
        "user" => [
            "Daniel" => ["01:18:08", "04:10:12"],
            "Fabian" => ["06:03:00"],
            "Max" => ["01:04:00", "04:10:12"],
            "Serto" => ["02:00:02"],
        ]
    ],
    "B" => [
        "color" => 'blue',
        "user" => [
            "Franz" => ["08:40:52", "14:05:32", "20:34:15"],
            "Hugo" => ["07:08:58", "04:10:12"],
        ]
    ],
    "C" => [
        "color" => 'green',
        "user" => [
            "Maxi" => ["07:08:58", "04:10:12"],
        ]
    ]
];

Advertisement

Answer

You cannot simply call array_merge_recursive() on the whole data sets because they will generated repeated color values, but you want the color values to remain singular and the user data to be recursively merged.

To accommodate this logic (assuming it is okay to simply mutate the $existingtArr array with the data from $newArr), perform a check for the existence of each letter-set, and either push the whole set for a non-present letter, or recursively merge the shared letter-sets.

Code: (Demo)

foreach ($newArr as $letter => $set) {
    if (!isset($existingtArr[$letter])) {
        $existingtArr[$letter] = $set;
    } else {
        $existingtArr[$letter]['user'] = array_merge_recursive(
            $existingtArr[$letter]['user'],
            $set['user']
        );
    }
}
var_export($existingtArr);
User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement