PHP: array_replace
Glossary overview

PHP: array_replace

The PHP array_replace() function replaces the values of the first array with values having the same keys from subsequent arrays. It does not work recursively; for recursive replacement, use array_replace_recursive()

Usage

$a = ['a' => 1, 'b' => 2];
$b = ['b' => 99];

$result = array_replace($a, $b);

// Output
['a' => 1, 'b' => 99]

Or we can add new element:

$a = ['a' => 1];
$b = ['b' => 2];

array_replace($a, $b);

// Output
['a' => 1, 'b' => 2]

Example with numerical indices:

$a = [10, 20, 30];
$b = [1 => 99];

array_replace($a, $b);

// Output
[10, 99, 30]

and

$defaults = [
    'limit' => 10,
    'sort'  => 'date',
];

$user = [
    'limit' => 50,
];

$config = array_replace($defaults, $user);

// Output
['limit' => 50, 'sort' => 'date']

Codewars example

You will be given an array of numbers. You have to sort the odd numbers in ascending order while leaving the even numbers at their original positions.

function sortArray(array $arr) : array {
  $vals = array_filter($arr, fn($v) => $v%2 != 0);
  $keys = array_keys($vals);
  sort($vals);
  return array_replace($arr, array_combine($keys, $vals));
}

Задача:
отсортировать только нечётные числа, не трогая чётные позиции.

Алгоритм здесь такой:

  1. Вытащить нечётные числа
  2. Запомнить их исходные позиции
  3. Отсортировать нечётные
  4. Поставить их обратно на те же позиции

И вот шаг 4 сделан очень элегантно через array_replace

array_filter

$vals = array_filter($arr, fn($v) => $v % 2 != 0);

Получаем только нечётные, ключи сохраняются.

[5, 3, 2, 8, 1, 4]
↓
$vals =
[
  0 => 5,
  1 => 3,
  4 => 1
]

array_keys

$keys = array_keys($vals);

Теперь у нас:

[0, 1, 4]

Это позиции, куда потом вернём отсортированные числа.

sort

sort($vals);

Теперь:

$vals = [1, 3, 5]

sort сбрасывает ключи → индексы становятся 0,1,2. Но нам ключи уже не нужны — мы их сохранили отдельно.

Главная магия — array_combine + array_replace

array_combine

array_combine($keys, $vals)

Создаёт массив:

[
  0 => 1,
  1 => 3,
  4 => 5
]

То есть:

отсортированные нечётные
снова привязаны к старым позициям

array_replace

array_replace($arr, ...)

Вот ключевой момент.

array_replace:

  • берёт оригинальный массив
  • заменяет значения только по совпадающим ключам
  • остальные элементы не трогает

Поэтому:

было: [5, 3, 2, 8, 1, 4]
замены: [0=>1, 1=>3, 4=>5]
стало: [1, 3, 2, 8, 5, 4]