The OP.'s requirement is to preserve keys (keep keys) and not overlap (I think overwrite). In some cases such as numeric keys it is possible but if string keys it seems to be not possible.
If you use array_merge()
the numeric keys will always re-index or renumbered.
If you use array_replace()
, array_replace_recursive()
it will be overlap or overwrite from the right to the left. The value with the same key on first array will be replaced with second array.
If you use $array1 + $array2
as the comment was mentioned, if the keys are same then it will keep the value from first array but drop the second array.
Custom function.
Here is my function that I just wrote to work on the same requirements. You are free to use for any purpose.
/**
* Array custom merge. Preserve indexed array key (numbers) but overwrite string key (same as PHP's `array_merge()` function).
*
* If the another array key is string, it will be overwrite the first array.<br>
* If the another array key is integer, it will be add to first array depend on duplicated key or not.
* If it is not duplicate key with the first, the key will be preserve and add to the first array.
* If it is duplicated then it will be re-index the number append to the first array.
*
* @param array $array1 The first array is main array.
* @param array ...$arrays The another arrays to merge with the first.
* @return array Return merged array.
*/
function arrayCustomMerge(array $array1, array ...$arrays): array
{
foreach ($arrays as $additionalArray) {
foreach ($additionalArray as $key => $item) {
if (is_string($key)) {
// if associative array.
// item on the right will always overwrite on the left.
$array1[$key] = $item;
} elseif (is_int($key) && !array_key_exists($key, $array1)) {
// if key is number. this should be indexed array.
// and if array 1 is not already has this key.
// add this array with the key preserved to array 1.
$array1[$key] = $item;
} else {
// if anything else...
// get all keys from array 1 (numbers only).
$array1Keys = array_filter(array_keys($array1), 'is_int');
// next key index = get max array key number + 1.
$nextKeyIndex = (intval(max($array1Keys)) + 1);
unset($array1Keys);
// set array with the next key index.
$array1[$nextKeyIndex] = $item;
unset($nextKeyIndex);
}
}// endforeach; $additionalArray
unset($item, $key);
}// endforeach;
unset($additionalArray);
return $array1;
}// arrayCustomMerge
Testing.
<?php
$array1 = [
'cat',
'bear',
'fruitred' => 'apple',
3 => 'dog',
null => 'null',
];
$array2 = [
1 => 'polar bear',
20 => 'monkey',
'fruitred' => 'strawberry',
'fruityellow' => 'banana',
null => 'another null',
];
// require `arrayCustomMerge()` function here.
function printDebug($message)
{
echo '<pre>';
print_r($message);
echo '</pre>' . PHP_EOL;
}
echo 'array1: <br>';
printDebug($array1);
echo 'array2: <br>';
printDebug($array2);
echo PHP_EOL . '<hr>' . PHP_EOL . PHP_EOL;
echo 'arrayCustomMerge:<br>';
$merged = arrayCustomMerge($array1, $array2);
printDebug($merged);
assert($merged[0] == 'cat', 'array key 0 should be \'cat\'');
assert($merged[1] == 'bear', 'array key 1 should be \'bear\'');
assert($merged['fruitred'] == 'strawberry', 'array key \'fruitred\' should be \'strawberry\'');
assert($merged[3] == 'dog', 'array key 3 should be \'dog\'');
assert(array_search('another null', $merged) !== false, '\'another null\' should be merged.');
assert(array_search('polar bear', $merged) !== false, '\'polar bear\' should be merged.');
assert($merged[20] == 'monkey', 'array key 20 should be \'monkey\'');
assert($merged['fruityellow'] == 'banana', 'array key \'fruityellow\' should be \'banana\'');
The results.
array1:
Array
(
[0] => cat
[1] => bear
[fruitred] => apple
[3] => dog
[] => null
)
array2:
Array
(
[1] => polar bear
[20] => monkey
[fruitred] => strawberry
[fruityellow] => banana
[] => another null
)
---
arrayCustomMerge:
Array
(
[0] => cat
[1] => bear
[fruitred] => strawberry
[3] => dog
[] => another null
[4] => polar bear
[20] => monkey
[fruityellow] => banana
)
array( 123 => "VALUE123" )
toarray( 0 => "VALUE123" )
– Cerealassert(array(0=>0,1=>1) === array_merge(array('9'=>0), array('9'=>1)))
– Suburb