+ operador para array em PHP?


192
$test = array('hi');
$test += array('test','oh');
var_dump($test);

O que +significa para matriz em PHP?


5
Percebo que sua pergunta teve +=e a resposta aceita teve +. Dos meus testes, eles parecem se comportar da mesma maneira.
user151841

7
A documentação resume tudo muito bem
artfulrobot


@RobbieAverill - esta é a pergunta à qual essa pergunta de referência se refere. Portanto, se qualquer coisa que pergunta Referência é a duplicata
icc97

2
Alguém mais está horrorizado com o fato de que uma coisa tão fundamental como a concatenação de matriz precisa ser realizada array_merge? É como se matrizes fossem matrizes associativas padrão e matrizes numéricas fossem cidadãos de segunda classe.
icc97

Respostas:


271

Citando o Manual do PHP sobre Operadores de Linguagem

O operador + retorna a matriz da direita anexada à matriz da esquerda; para chaves que existem em ambas as matrizes, os elementos da matriz à esquerda serão usados ​​e os elementos correspondentes da matriz à direita serão ignorados.

Então se você faz

$array1 = ['one',   'two',          'foo' => 'bar'];
$array2 = ['three', 'four', 'five', 'foo' => 'baz']; 

print_r($array1 + $array2);

Você vai ter

Array
(
    [0] => one   // preserved from $array1 (left-hand array)
    [1] => two   // preserved from $array1 (left-hand array)
    [foo] => bar // preserved from $array1 (left-hand array)
    [2] => five  // added from $array2 (right-hand array)
)

Portanto, a lógica de +é equivalente ao seguinte snippet:

$union = $array1;

foreach ($array2 as $key => $value) {
    if (false === array_key_exists($key, $union)) {
        $union[$key] = $value;
    }
}

Se você estiver interessado nos detalhes da implementação em nível C, vá para


Observe que isso +é diferente de como array_merge()combinar as matrizes:

print_r(array_merge($array1, $array2));

te daria

Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [foo] => baz // overwritten from $array2
    [2] => three // appended from $array2
    [3] => four  // appended from $array2
    [4] => five  // appended from $array2
)

Veja as páginas vinculadas para mais exemplos.


1
@Pacerier PHP produzido por php.net não tem uma especificação formal, mas tanto o +e array_mergechamada zend_hash_mergesob o capô. Isso também é esperado, já que em matrizes PHP são implementadas como mapas de hash ordenados.
bispo

1
@Pacerier Os documentos on-line do php.net são o registro mais próximo de uma especificação, mas na IMO esses documentos ficam muito aquém de uma especificação verdadeira: primeiro, eles são atualizados depois que o código é escrito; segundo, eles não foram escritos para cobrir todos os usos especiais.
bispo

14
O comportamento do PHP +e array_mergeé perverso e pouco intuitivo. Eles são o caminho oposto ao que uma leitura em inglês comum diria intuitivamente para você 'adicionar' ou 'mesclar' matrizes. Outras linguagens / bibliotecas usam +para concatenar listas (por exemplo, em Python) e funções "mesclar" para adicionar os pares de chave / valor de um objeto para outro (por exemplo, em lodash). No entanto, no PHP é o contrário; array_mergepode ser usado para concatenar matrizes do tipo lista, mas +não pode. Ao contrário array_merge, +sempre executa a operação que seria chamada de "mesclagem" em qualquer outro idioma.
Mark-Augy

1
@ icc97 eles são de fato apenas HashMaps. Veja nikic.github.io/2014/12/22/…
Gordon

2
Tentei enviar um bug para ver se um alias array_concatpoderia ser criado array_merge.
icc97

18

O melhor exemplo que encontrei para usar isso está em uma matriz de configuração.

$user_vars = array("username"=>"John Doe");
$default_vars = array("username"=>"Unknown", "email"=>"no-reply@domain.com");

$config = $user_vars + $default_vars;

O $default_vars, como sugere, é a matriz para os valores padrão. A $user_varsmatriz substituirá os valores definidos em $default_vars. Quaisquer valores ausentes em $user_varsagora são os padrões de Vars $default_vars.

Isso seria print_rcomo:

Array(2){
    "username" => "John Doe",
    "email" => "no-reply@domain.com"
}

Eu espero que isso ajude!


6

Esse operador adota a união de duas matrizes (o mesmo que array_merge, exceto que, com array_merge, as chaves duplicadas são substituídas).

A documentação para operadores de matriz é encontrada aqui .


1
Uma palavra de cautela para iniciantes aqui, o resultado da operação é nulo se qualquer uma das matrizes for nula . Alguns podem não se importar com isso, pois se trata de uma operação de união, o resultado será a matriz (não nula) adequada se uma delas for nula. Mas isso vale se uma das matrizes for uma matriz vazia .
Sandeepan Nath 13/07/12

Portanto, como boa prática, acho, devemos inicializar as matrizes de entrada como matrizes vazias. O que vocês dizem?
Sandeepan Nath 13/07/12

5

Cuidado com as teclas numéricas, se elas devem ser preservadas ou se você não quer perder nada

$a = array(2 => "a2", 4 => "a4", 5 => "a5");
$b = array(1 => "b1", 3 => "b3", 4 => "b4");

União

print_r($a+$b);
Array
(
    [2] => a2
    [4] => a4
    [5] => a5
    [1] => b1
    [3] => b3
)

fundir

print_r(array_merge($a, $b));
Array
(
    [0] => a2
    [1] => a4
    [2] => a5
    [3] => b1
    [4] => b3
    [5] => b4
)

3

O +operador produz os mesmos resultados que array_replace () . No entanto, como os argumentos do operador são revertidos, a ordem da matriz resultante também pode ser diferente.

Expandindo em outro exemplo desta página:

$array1 = array('one', 'two', 'foo' => 'bar');
$array2 = array('three', 'four', 'five', 'foo' => 'baz'); 

print_r($array1 + $array2);
print_r(array_replace($array2, $array1)); //note reversed argument order

saídas:

Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [foo] => bar // preserved from $array1
    [2] => five  // added from $array2
)
Array
(
    [0] => one   // preserved from $array1
    [1] => two   // preserved from $array1
    [2] => five  // added from $array2
    [foo] => bar // preserved from $array1
)

A ordem é +garantida pelas especificações? Que tal array_replace?
Pacerier 30/03

1
  1. Matriz mais operação trata toda matriz como matriz associada.
  2. Quando o conflito de teclas durante o sinal de mais, o valor esquerdo (anterior) será mantido

Eu posto o código abaixo para esclarecer as coisas.

$a + $b = array_plus($a, $b)

function array_plus($a, $b){
    $results = array();
    foreach($a as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
    foreach($b as $k=>$v) if(!isset($results[$k]))$results[$k] = $v;
    return $results;
}

A execução do código do @ Tamlyn parece provar que sua afirmação "matriz mais operação trata toda matriz como matriz assoc" está errada.
Pacerier 30/03

@Pacerier essa chave também pode ser um número inteiro.
Hitesh


-4
$var1 = "example";
$var2 = "test";
$output = array_merge((array)$var1,(array)$var2);
print_r($output);

Matriz ([0] => exemplo [1] => teste)


1
Este tópico menciona algumas vezes como array_merge () NÃO é congruente.
doublejosh

@doublejosh, "congruente"? Significado?
Pacerier 30/03

1
Eles não são os mesmos.
doublejosh
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.