Combine duas matrizes


91

Eu tenho duas matrizes como esta:

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

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

Eu quero combinar essas duas matrizes de modo que não contenha duplicatas e também mantenha suas chaves originais. Por exemplo, a saída deve ser:

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

Eu tentei isso, mas está mudando suas chaves originais:

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

Qualquer solução?

Respostas:


165

Apenas use:

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

Isso deve resolver o problema. Porque você usa chaves de string se uma chave ocorrer mais de uma vez (como '44'em seu exemplo), uma chave substituirá as de procedimento com o mesmo nome. Porque no seu caso ambos têm o mesmo valor, de qualquer forma, não importa e também removerá duplicatas.

Update: Acabei de perceber que o PHP trata as chaves de string numéricas como números (inteiros) e por isso vai se comportar assim, o que significa que ele renumera as chaves também ...

Uma solução alternativa é recriar as chaves.

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

Atualização 2: Sempre esqueço que também há uma operadora (em negrito, porque é isso que você está procurando!: D)

$output = $array1 + $array2;

Tudo isso pode ser visto em: http://php.net/manual/en/function.array-merge.php


5
@KingCrunch - Mesmo que os números estejam entre aspas, eles não são chaves de string e, portanto, o índice não será preservado. Exemplo: ideone.com/I2NFT
Brendan Bullen

1
Sério ... Primeiro eu queria falar sobre "um bug", mas depois percebi que o manual só fala sobre "teclas numéricas", não "teclas inteiras". É um pouco confuso.
KingCrunch

+1 Esqueci a operadora! Excelente (coloque essa parte em negrito
!;

4
Portanto, $array1 + $array2é uma solução curta e eficiente em vez de uma array_merge() - array_combine()combinação
Awan

2
ATENÇÃO! para matrizes não associadas ou se as matrizes tiverem chaves comuns$a + $b != array_merge($a, $b)
jmarceli

33

Você deve levar em consideração que $array1 + $array2 != $array2 + $array1

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

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

com $ array1 + $ array2

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

e com $ array2 + $ array1

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

25

Isso funciona:

$output = $array1 + $array2;

12
Eu não recomendaria isso porque seu comportamento é muito pouco intuitivo, por exemplo[1,2,3] + [4,5,6] == [1,2,3]
jchook

@jchook O que você recomenda então?
Michas

Isso é o que eu precisava, obrigado. Eis o porquê: http_build_query(array_merge($array1, $array2))não funcionou para mim, mas http_build_query($array1 + $array2)funcionou.
BarryMode

4

Para fazer isso, você pode percorrer um e anexar ao outro:

<?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));

?>

ATUALIZAÇÃO: KingCrunch surgiu com a melhor solução :print_r($array1+$array2);


2

Se você estiver usando PHP 7.4 ou superior, pode usar o operador spread ...como os seguintes exemplos dos documentos do 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]

Funciona como no JavaScript ES6.

Veja mais em https://wiki.php.net/rfc/spread_operator_for_array .


Isso não se aplica à questão. O OP tem chaves de string para o array (Isso não funciona com o operador de propagação) e o OP deseja preservar as chaves (o operador de propagação joga fora as chaves). Também OP não quer duplicatas.
martti

Oh, eu vejo seus pontos. Isso é verdade e você está certo. Você pode fornecer algum código para nos ajudar a melhorar minha resposta para outras pessoas? Eu aprecio seu tempo! Muito obrigado por apontar as desvantagens da minha resposta.
Estudante de Ciências de

Não acho que a operadora de propagação seja a melhor opção aqui. Em vez disso, use a resposta dada$array1 + $array2
martti

Eu não estava ciente disso! Quer dizer, eu não sabia o que poderíamos fazer $ouput = $array1 + $array2. Agora aprendi algo novo! Obrigado!
Estudante de Ciências,

1

Isso funciona:

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

1

Atenção! $ array1 + $ array2 sobrescreve as chaves, então minha solução (para arrays multidimensionais) é usar array_unique ()

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

Aviso prévio:

5.2.10+ Alterado o valor padrão de sort_flagsvolta para SORT_STRING.

5.2.9 O padrão é SORT_REGULAR.

5.2.8- O padrão é SORT_STRING

Funciona perfeitamente . Espero que ajude mesmo.


1
array_merge()não preserva as chaves. A matriz criada por isso é 0 indexada.
HPierce

@HPierce bem, no caso de adição de array multidimensional, algumas informações serão perdidas usando +. Dê uma olhada em: PHPFiddle , $ b [0] serão perdidos ...
Norman Edance

1

A nova maneira de fazer isso com php7.4 é o operador Spread [...]

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

O operador Spread deve ter melhor desempenho do que array_merge

Uma vantagem significativa do operador Spread é que ele oferece suporte a quaisquer objetos percorríveis, enquanto a função array_merge oferece suporte apenas a matrizes.


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.