joachim
joachim

Reputation: 30791

array_replace_recursive() without creation of keys

In PHP, array_replace_recursive() does two things according to the documentation:

Is there an alternative that only does the replacement, and doesn't create new keys?

For example:

$array = [
  'apple' => TRUE,
  'pear' => TRUE,
  'basket' => [
    'banana' => TRUE,
  ],
  'punnet' => [
    'strawberry' => TRUE,
  ],
];

$replacement = [
  'banana' => [
    'REPLACEMENT!'
  ],
];

The result should be:

$array = [
  'apple' => TRUE,
  'pear' => TRUE,
  'basket' => [
    'banana' => [
      'REPLACEMENT!'
    ],
  ],
  'punnet' => [
    'strawberry' => TRUE,
  ],
];

Upvotes: 1

Views: 644

Answers (2)

joachim
joachim

Reputation: 30791

This does what I needed:

array_walk_recursive($array, function(&$value, $key, $replacements) {
  if (isset($replacements[$key])) {
    $value = $replacements[$key];
  }
}, ['replace' => 'replacement']);

Upvotes: 0

Prince Dorcis
Prince Dorcis

Reputation: 1045

You will need to use array_intersect_key() to create an array that contains only the keys that are in the two arrays, then you can merge.

$array1 = [
    'a' => 1,
    'b' => 2,
    'c' => 3,
    'd' => 4,
];

$array2 = [
    'b' => 14,
    'c' => 70,
    'f' => 5,
];

// $array2 has to be the first arguments for $inter to have its value instead of the value of $array1
$inter = array_intersect_key($array2, $array1);

$merged = array_replace_recursive($array1, $inter);

// Merged will be: 
[
    'a' => 1,
    'b' => 14,
    'c' => 70,
    'd' => 4,
];

EDIT For this to work recursively, you can use this function found here

/** 
* Recursively computes the intersection of arrays using keys for comparison.
* 
* @param   array $array1 The array with master keys to check.
* @param   array $array2 An array to compare keys against.
* @return  array associative array containing all the entries of array1 which have keys that are present in array2.
**/
function array_intersect_key_recursive(array $array1, array $array2) {
    $array1 = array_intersect_key($array1, $array2);

    foreach ($array1 as $key => &$value) {
        if (is_array($value) && is_array($array2[$key])) {
            $value = array_intersect_key_recursive($value, $array2[$key]);
        }
    }

    return $array1;
}

Upvotes: 0

Related Questions