PHP: ¿fusionar dos matrices manteniendo las claves en lugar de reindexar?

255

¿Cómo puedo fusionar dos matrices (una con string => pares de valores y otra con int => pares de valores) mientras mantengo las teclas string / int? Ninguno de ellos se superpondrá (porque uno solo tiene cadenas y el otro solo tiene números enteros).

Aquí está mi código actual (que no funciona, porque array_merge está reindexando la matriz con teclas enteras):

// 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
fuente
1
Eso es extraño: según la página de documentación de PHP, array_merge no debería hacer eso. ¿Las teclas de cadena son en realidad representaciones de cadenas de enteros?
owenmarshall
array_merge está reindexando mi segunda matriz. es decir. está cambiando la matriz de array( 123 => "VALUE123" )aarray( 0 => "VALUE123" )
Garrett
hmm, eso es interesante Supongo que la documentación de PHP podría ser un poco confusa en ese punto. Dice lo que sucederá si todas las matrices tienen claves numéricas, pero no dice específicamente qué sucederá si no lo tienen.
Steven Oxley
Quizás no hace 2 años. Pero en 2012, la documentación es clara en este punto.
cartbeforehorse
En realidad, la documentación aún no es clara como el cristal. "Numérico" en realidad incluye una cadena con todos los dígitos (PHP 5.3.3). assert(array(0=>0,1=>1) === array_merge(array('9'=>0), array('9'=>1)))
Bob Stein

Respuestas:

557

Simplemente puede 'agregar' las matrices:

>> $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
fuente
44
¡Sé muy cuidadoso con esto! El operador + no es una adición, es una unión. Si las teclas no se superponen, entonces todo está bien, pero si lo hacen ...
GordonM
3
Simplemente guau: me salvaste cubos de líneas de código, casi tres años después.
Stephen O'Flynn
86
En caso de que alguien se pregunte "¿y si se superponen?" : php.net: "El operador + devuelve la matriz de la derecha adjunta a la matriz de la izquierda; para las claves que existen en ambas matrices, se utilizarán los elementos de la matriz de la izquierda y los elementos coincidentes de la derecha -hand array será ignorado ".
Flion
2
@Flion es más complicado que eso. Usando '+', acabo de agregar dos sub-matrices con un elemento con una clave y subclave común: ¡los valores se agregaron! 100000 => array (tamaño = 3) 1 => int 128 2 => int 56 3 => int 7 + 100000 => array (tamaño = 1) 2 => int 30 Resultado: 100000 => array (tamaño = 3) 1 => int 128 2 => int 86 3 => int 7 Básicamente, agregar [2 => 56] + [2 => 30] no reemplazó el valor pero lo agregó y se convirtió en [2 => 86]
Dario Fumagalli
1
@DarioFumagalli No sé si estoy malentendido o si solo ha cambiado desde 2016, pero en este momento, la operación print_r([2 => 56] + [2 => 30]);rinde Array ( [2] => 56 ). Entonces, mantiene el lado izquierdo como se especifica. Esto es a partir de PHP 7.1.19, que se ejecuta en repl.it .
Charles Wood
62

Teniendo en cuenta que tienes

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

Haciendo $merge = $replacement + $replaced;saldrá:

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

La primera matriz de suma tendrá valores en la salida final.

Haciendo $merge = $replaced + $replacement;saldrá:

Array('1' => 'value1', '4' => 'value4', '6' => 'value3');
CRK
fuente
[[thumbsup]] en este
Jhourlad Estrella
21
En resumen, al agregar 2 matrices, los valores de la primera anulan los valores de la segunda.
Dziamid el
1
Pensé que el segundo anulará al primero. :)
Asim KT
1
Exactamente. Por eso no pude usar $allValues += $newValues;.
MarthyM
Haciendo $merge = $replacement + $replaced;salir:Array ( [4] => value2 [6] => value3 [1] => value1 )
Chandan Sharma
24

Si bien esta pregunta es bastante antigua, solo quiero agregar otra posibilidad de hacer una fusión mientras mantengo las claves.

Además de agregar claves / valores a las matrices existentes utilizando el +signo, puede hacer un array_replace.

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

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

El resultado será:

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

La misma matriz sobrescribirá las mismas claves.
También hay unarray_replace_recursive , que hace esto también para las submatrices.

Ejemplo en vivo en 3v4l.org

danopz
fuente
3

Se pueden agregar o unir fácilmente dos matrices sin cambiar su indexación original por el operador + . Esto será de gran ayuda en el menú desplegable de selección de laravel y codeigniter.

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

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

  $arr_option = $empty_option + $option_list;

La salida será:

$arr_option = array(
   ''=>'Select Option'
   1=>'Red',
   2=>'White',
   3=>'Green',
 );
amba patel
fuente
1

Pruebe las funciones array_replace_recursive o 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

zdenek
fuente