Combinez deux tableaux

88

J'ai deux tableaux comme celui-ci:

array( 
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44'
);

array( 
'44' => '44',
'55' => '55',
'66' => '66',
'77' => '77'
);

Je veux combiner ces deux tableaux de manière à ce qu'il ne contienne pas de doublon et conserve leurs clés d'origine. Par exemple, la sortie doit être:

array( 
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44',
'55' => '55',
'66' => '66',
'77' => '77'
);

J'ai essayé cela mais cela change leurs clés d'origine:

$output = array_unique( array_merge( $array1 , $array2 ) );

Toute solution?

Awan
la source

Réponses:

161

Utilisez simplement:

$output = array_merge($array1, $array2);

Cela devrait le résoudre. Parce que vous utilisez des clés de chaîne si une clé se produit plus d'une fois (comme '44'dans votre exemple), une clé écrasera celles en cours avec le même nom. Parce que dans votre cas, ils ont tous les deux la même valeur de toute façon, cela n'a pas d'importance et cela supprimera également les doublons.

Mise à jour: Je viens de réaliser que PHP traite les touches de chaîne numériques comme des nombres (entiers) et se comportera donc comme ceci, ce qui signifie qu'il renumérote également les clés ...

Une solution de contournement consiste à recréer les clés.

$output = array_combine($output, $output);

Mise à jour 2: j'oublie toujours, qu'il y a aussi un opérateur (en gras, car c'est vraiment ce que vous recherchez!: D)

$output = $array1 + $array2;

Tout cela peut être vu sur: http://php.net/manual/en/function.array-merge.php

KingCrunch
la source
5
@KingCrunch - Même si les nombres sont entre guillemets, ce ne sont pas des clés de chaîne et donc l'index ne sera pas conservé. Exemple: ideone.com/I2NFT
Brendan Bullen
1
Vraiment ... Je voulais d'abord parler "d'un bug", mais ensuite j'ai remarqué que le manuel ne parle que de "touches numériques", pas de "touches entières". C'est un peu déroutant.
KingCrunch
+1 J'ai oublié l'opérateur! Excellent (mettez cette partie en gras!;))
Brendan Bullen
3
Il en $array1 + $array2va de même pour une solution courte et efficace au lieu de la array_merge() - array_combine()combinaison
Awan
2
ATTENTION! pour les tableaux non-associés ou si les tableaux ont des clés communes$a + $b != array_merge($a, $b)
jmarceli
33

Vous devriez prendre en considération que $array1 + $array2 != $array2 + $array1

$array1 = array(
'11' => 'x1',
'22' => 'x1' 
);  

$array2 = array(
'22' => 'x2',
'33' => 'x2' 
);

avec $ array1 + $ array2

$array1 + $array2 = array(
'11' => 'x1',
'22' => 'x1',
'33' => 'x2'
);

et avec $ array2 + $ array1

$array2 + $array1 = array(  
'11' => 'x1',  
'22' => 'x2',  
'33' => 'x2'  
);
inemanja
la source
25

Cela marche:

$output = $array1 + $array2;
Michas
la source
12
Je ne recommanderais pas cela car son comportement est très peu intuitif, par exemple[1,2,3] + [4,5,6] == [1,2,3]
jchook
@jchook Que recommandez-vous alors?
Michas
C'est ce dont j'avais besoin, merci. Voici pourquoi: http_build_query(array_merge($array1, $array2))n'a pas fonctionné pour moi, alors que je l' http_build_query($array1 + $array2)ai fait.
BarryMode
4

Pour ce faire, vous pouvez parcourir l'un et l'ajouter à l'autre:

<?php

$test1 = array( 
'11' => '11',
'22' => '22',
'33' => '33',
'44' => '44'
);

$test2 = array( 
'44' => '44',
'55' => '55',
'66' => '66',
'77' => '77'
);


function combineWithKeys($array1, $array2)
{
    foreach($array1 as $key=>$value) $array2[$key] = $value;
    asort($array2);
    return $array2;
} 

print_r(combineWithKeys($test1, $test2));

?>

MISE À JOUR: KingCrunch a proposé la meilleure solution :print_r($array1+$array2);

Brendan Bullen
la source
2

Si vous utilisez PHP 7.4 ou supérieur, vous pouvez utiliser l'opérateur de diffusion ...comme les exemples suivants de la documentation PHP:

$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; //[1, 2, 3]
$arr3 = [0, ...$arr1]; //[0, 1, 2, 3]
$arr4 = array(...$arr1, ...$arr2, 111); //[1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; //[1, 2, 3, 1, 2, 3]

function getArr() {
  return ['a', 'b'];
}
$arr6 = [...getArr(), 'c']; //['a', 'b', 'c']

$arr7 = [...new ArrayIterator(['a', 'b', 'c'])]; //['a', 'b', 'c']

function arrGen() {
    for($i = 11; $i < 15; $i++) {
        yield $i;
    }
}
$arr8 = [...arrGen()]; //[11, 12, 13, 14]

Cela fonctionne comme dans JavaScript ES6.

En savoir plus sur https://wiki.php.net/rfc/spread_operator_for_array .

Étudiant en sciences
la source
Cela ne s'applique pas à la question. L'OP a des clés de chaîne pour le tableau (cela ne fonctionne pas avec l'opérateur de propagation) et l'OP veut conserver les clés (l'opérateur de propagation jette les clés). De plus, OP ne veut pas de doublons.
martti
Oh je vois vos points. C'est vrai et vous avez raison. Pouvez-vous fournir un code pour nous aider à améliorer ma réponse pour d'autres personnes? J'apprécierais votre temps! Merci beaucoup d'avoir souligné les inconvénients de ma réponse.
Student of Science
Je ne pense pas que l'opérateur de diffusion soit la voie à suivre ici. Utilisez plutôt la réponse donnée$array1 + $array2
martti
Je n'étais pas au courant de cela! Je veux dire, je ne savais pas que nous pouvions le faire $ouput = $array1 + $array2. Maintenant, j'ai appris quelque chose de nouveau! Merci!
Student of Science
1

Cela marche:

$a = array(1 => 1, 2 => 2, 3 => 3);
$b = array(4 => 4, 5 => 5, 6 => 6);
$c = $a + $b;
print_r($c);
jeni
la source
1

Attention! $ array1 + $ array2 écrase les clés, donc ma solution (pour les tableaux multidimensionnels) est d'utiliser array_unique ()

array_unique(array_merge($a, $b), SORT_REGULAR);

Remarquer:

5.2.10+ Modification de la valeur par défaut de sort_flagsback en SORT_STRING.

5.2.9 La valeur par défaut est SORT_REGULAR.

5.2.8- La valeur par défaut est SORT_STRING

Cela fonctionne parfaitement . J'espère que cela aide la même chose.

Norman Edance
la source
1
array_merge()ne conserve cependant pas les clés. Le tableau créé par cela est 0 indexé.
HPierce
@HPierce bien, dans le cas d'ajout de tableau multidimensionnel, certaines informations seront perdues en utilisant +. Jetez un œil à: PHPFiddle , $ b [0] sera perdu ...
Norman Edance
1

La nouvelle façon de le faire avec php7.4 est l'opérateur Spread [...]

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
var_dump($fruits);

L'opérateur d'épandage devrait avoir de meilleures performances que array_merge

Un avantage significatif de l'opérateur Spread est qu'il prend en charge tous les objets traversables, tandis que la fonction array_merge ne prend en charge que les tableaux.

Shoaib Ahmed
la source