PHP: fusionner deux tableaux tout en conservant les clés au lieu de réindexer?

255

Comment puis-je fusionner deux tableaux (un avec chaîne => paires de valeurs et un autre avec int => paires de valeurs) tout en conservant les clés chaîne / int? Aucun d'entre eux ne se chevauchera jamais (car l'un n'a que des chaînes et l'autre n'a que des entiers).

Voici mon code actuel (qui ne fonctionne pas, car array_merge ré-indexe le tableau avec des clés entières):

// 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
la source
1
C'est étrange: selon la page de documentation PHP, array_merge ne devrait pas faire ça. Les clés de chaîne sont-elles en fait des représentations de chaîne d'entiers?
owenmarshall
array_merge réindexe mon deuxième tableau. c'est à dire. il est en train de changer le tableau de array( 123 => "VALUE123" )àarray( 0 => "VALUE123" )
Garrett
hmm, c'est intéressant. Je suppose que la documentation PHP pourrait être un peu floue sur ce point. Il indique ce qui se passera si tous les tableaux ont des touches numériques, mais il ne dit pas spécifiquement ce qui se passera s'ils ne le font pas.
Steven Oxley
peut-être pas il y a 2 ans. Mais en 2012, la documentation est limpide sur ce point.
cartbeforehorse
En fait, la documentation n'est toujours pas limpide. "Numeric" inclut en fait une chaîne avec tous les chiffres (PHP 5.3.3). assert(array(0=>0,1=>1) === array_merge(array('9'=>0), array('9'=>1)))
Bob Stein

Réponses:

557

Vous pouvez simplement «ajouter» les tableaux:

>> $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
la source
44
Soyez très prudent avec cela! L'opérateur + n'est pas un ajout, c'est une union. Si les touches ne se chevauchent pas, alors tout va bien, mais si c'est le cas ...
GordonM
3
Wow, vous m'avez sauvé des seaux de lignes de code, près de trois ans plus tard.
Stephen O'Flynn
86
Au cas où quelqu'un se demanderait «et s'ils se chevauchent? : php.net: "L'opérateur + renvoie le tableau de droite ajouté au tableau de gauche; pour les clés qui existent dans les deux tableaux, les éléments du tableau de gauche seront utilisés et les éléments correspondants de droite -tableau sera ignoré. "
Flion
2
@Flion c'est plus compliqué que ça. En utilisant '+', je viens d'ajouter deux sous-tableaux avec un élément avec une clé et une sous-clé communes: les valeurs ont été ajoutées! 100000 => tableau (taille = 3) 1 => int 128 2 => int 56 3 => int 7 + 100000 => tableau (taille = 1) 2 => int 30 Résultat: 100000 => tableau (taille = 3) 1 => int 128 2 => int 86 3 => int 7 En gros, l'ajout de [2 => 56] + [2 => 30] n'a pas remplacé la valeur mais l'a ajoutée et est devenu [2 => 86]
Dario Fumagalli
1
@DarioFumagalli Je ne sais pas si je me méprends ou si c'est juste changé depuis 2016, mais à ce stade, l'opération print_r([2 => 56] + [2 => 30]);cède Array ( [2] => 56 ). Donc, il garde le côté gauche comme spécifié. Ceci est PHP 7.1.19, en cours d' exécution sur repl.it .
Charles Wood
62

Considérant que vous avez

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

Faire $merge = $replacement + $replaced;produira:

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

Le premier tableau de sum aura des valeurs dans la sortie finale.

Faire $merge = $replaced + $replacement;produira:

Array('1' => 'value1', '4' => 'value4', '6' => 'value3');
CRK
la source
[[thumbsup]] sur celui-ci
Jhourlad Estrella
21
Pour résumer, lors de l'ajout de 2 tableaux, les valeurs du premier remplacent les valeurs du second.
Dziamid
1
Je pensais que le second l'emporterait sur le premier. :)
Asim KT
1
Exactement. Voilà pourquoi je ne pouvais pas utiliser $allValues += $newValues;.
MarthyM
Faire $merge = $replacement + $replaced;produira:Array ( [4] => value2 [6] => value3 [1] => value1 )
Chandan Sharma
24

Bien que cette question soit assez ancienne, je veux simplement ajouter une autre possibilité de fusionner tout en conservant les clés.

En plus d'ajouter des clés / valeurs aux tableaux existants en utilisant le +signe que vous pourriez faire array_replace.

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

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

Le résultat sera:

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

Les mêmes clés seront écrasées par ce dernier tableau.
Il existe également un array_replace_recursive, qui le fait également pour les sous-réseaux.

Exemple en direct sur 3v4l.org

danopz
la source
3

Deux tableaux peuvent être facilement ajoutés ou réunis sans modifier leur indexation d'origine par l' opérateur + . Ce sera très utile dans laravel et la liste déroulante de sélection de codeigniter.

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

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

  $arr_option = $empty_option + $option_list;

La sortie sera:

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

Essayez les fonctions array_replace_recursive ou 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
la source