PHP: объединить два массива, сохраняя ключи вместо переиндексации?

255

Как можно объединить два массива (один с парами строка => значение, а другой с парами значение =>), сохраняя ключи строка / int? Ни один из них никогда не будет перекрываться (потому что у одного есть только строки, а у другого только целые числа).

Вот мой текущий код (который не работает, потому что array_merge переиндексирует массив целочисленными ключами):

// get all id vars by combining the static and dynamic
$staticIdentifications = array(
 Users::userID => "USERID",
 Users::username => "USERNAME"
);
// get the dynamic vars, formatted: varID => varName
$companyVarIdentifications = CompanyVars::getIdentificationVarsFriendly($_SESSION['companyID']);
// merge the static and dynamic vars (*** BUT KEEP THE INT INDICES ***)
$idVars = array_merge($staticIdentifications, $companyVarIdentifications);
Garrett
источник
1
Это странно: согласно странице документации PHP, array_merge не должна этого делать. Являются ли строковые ключи действительно строковыми представлениями целых чисел?
owenmarshall
array_merge переиндексирует мой второй массив. то есть. это меняет массив с array( 123 => "VALUE123" )наarray( 0 => "VALUE123" )
Гарретт
хм, это интересно Я предполагаю, что документация PHP может быть немного неясной в этом вопросе. В нем говорится, что произойдет, если все массивы имеют цифровые клавиши, но в нем конкретно не говорится, что произойдет, если они этого не сделают.
Стивен Оксли
возможно не 2 года назад. Но в 2012 году документация кристально ясна по этому вопросу.
верховая лошадь
На самом деле, документация до сих пор не совсем ясна. «Числовой» фактически включает строку со всеми цифрами (PHP 5.3.3). assert(array(0=>0,1=>1) === array_merge(array('9'=>0), array('9'=>1)))
Боб Стейн

Ответы:

557

Вы можете просто «добавить» массивы:

>> $a = array(1, 2, 3);
array (
  0 => 1,
  1 => 2,
  2 => 3,
)
>> $b = array("a" => 1, "b" => 2, "c" => 3)
array (
  'a' => 1,
  'b' => 2,
  'c' => 3,
)
>> $a + $b
array (
  0 => 1,
  1 => 2,
  2 => 3,
  'a' => 1,
  'b' => 2,
  'c' => 3,
)
SirDarius
источник
44
Будьте ОЧЕНЬ осторожны с этим! Оператор + это не дополнение, это объединение. Если ключи не пересекаются, то все хорошо, но если они ...
GordonM
3
Просто вау - ты спас мне кучу строк кода, почти три года спустя.
Стивен О'Флинн
86
В случае, если кто-то задается вопросом «что, если они действительно перекрываются?» : php.net: "Оператор + возвращает правый массив, добавленный к левому массиву; для ключей, которые существуют в обоих массивах, будут использоваться элементы из левого массива и соответствующие элементы справа массив будет игнорироваться. "
Флион
2
@Flion это сложнее, чем это. Используя '+', я только что добавил два подмассива с элементом с общим ключом и подключом: значения были добавлены! 100000 => массив (размер = 3) 1 => int 128 2 => int 56 3 => int 7 + 100000 => массив (размер = 1) 2 => int 30 Результат: 100000 => массив (размер = 3) 1 => int 128 2 => int 86 3 => int 7 По существу, добавление [2 => 56] + [2 => 30] не заменило значение, но добавило его и стало [2 => 86]
Дарио Фумагалли,
1
@DarioFumagalli Я не знаю, неправильно ли я понимаю или просто изменилось с 2016 года, но на данный момент операция print_r([2 => 56] + [2 => 30]);приносит свои плоды Array ( [2] => 56 ). Таким образом, он держит левую сторону, как указано. Это , как в PHP 7.1.19, работает на repl.it .
Чарльз Вуд
62

Учитывая, что у вас есть

$replaced = array('1' => 'value1', '4' => 'value4');
$replacement = array('4' => 'value2', '6' => 'value3');

Делать $merge = $replacement + $replaced;будет выводить:

Array('4' => 'value2', '6' => 'value3', '1' => 'value1');

Первый массив из суммы будет иметь значения в конечном выводе.

Делать $merge = $replaced + $replacement;будет выводить:

Array('1' => 'value1', '4' => 'value4', '6' => 'value3');
ЦРК
источник
[[thumbsup]] на этот раз
Jhourlad Estrella
21
Подводя итог, при добавлении 2 массивов, значения из первого переопределяют значения из второго.
Дзиамид
1
Я думал, что второе заменит первое. :)
Asim KT
1
Именно. Вот почему я не мог использовать $allValues += $newValues;.
MarthyM
Делать $merge = $replacement + $replaced;будет выводить:Array ( [4] => value2 [6] => value3 [1] => value1 )
Чандан Шарма
24

Хотя этот вопрос довольно старый, я просто хочу добавить еще одну возможность слияния при сохранении ключей.

Помимо добавления ключа / значений к существующим массивам, используя +знак, который вы можете сделать array_replace.

$a = array('foo' => 'bar', 'some' => 'string');
$b = array(42 => 'answer to the life and everything', 1337 => 'leet');

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

Результат будет:

Array
(
  [foo] => bar
  [some] => string
  [42] => answer to the life and everything
  [1337] => leet
)

Те же ключи будут перезаписаны последним массивом.
Существует также метод array_replace_recursive, который делает это и для подмассивов.

Живой пример на 3v4l.org

danopz
источник
3

Два массива можно легко добавить или объединить, не изменяя их первоначальное индексирование с помощью оператора + . Это очень поможет в выпадающем списке laravel и codeigniter.

 $empty_option = array(
         ''=>'Select Option'
          );

 $option_list = array(
          1=>'Red',
          2=>'White',
          3=>'Green',
         );

  $arr_option = $empty_option + $option_list;

Выход будет:

$arr_option = array(
   ''=>'Select Option'
   1=>'Red',
   2=>'White',
   3=>'Green',
 );
амба патель
источник
1

Попробуйте функции array_replace_recursive или array_replace

$a = array('userID' => 1, 'username'=> 2);
array (
  userID => 1,
  username => 2
)
$b = array('userID' => 1, 'companyID' => 3);
array (
  'userID' => 1,
  'companyID' => 3
)
$c = array_replace_recursive($a,$b);
array (
  userID => 1,
  username => 2,
  companyID => 3
)

http://php.net/manual/en/function.array-replace-recursive.php

Зденек
источник