Połącz dwie tablice

88

Mam dwie takie tablice:

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

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

Chcę połączyć te dwie tablice tak, aby nie zawierały zduplikowanych, a także zachować ich oryginalne klucze. Na przykład wynik powinien wyglądać następująco:

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

Próbowałem tego, ale zmienia się ich oryginalne klucze:

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

Jakieś rozwiązanie?

Awan
źródło

Odpowiedzi:

161

Po prostu użyj:

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

To powinno rozwiązać problem. Ponieważ używasz kluczy łańcuchowych, jeśli jeden klucz występuje więcej niż jeden raz (jak '44'w twoim przykładzie), jeden klucz nadpisze klucze proceduralne o tej samej nazwie. Ponieważ w twoim przypadku oba i tak mają tę samą wartość, nie ma to znaczenia, a także usunie duplikaty.

Aktualizacja: Właśnie zdałem sobie sprawę, że PHP traktuje klawisze numeryczne jako liczby (liczby całkowite) i tak będzie się zachowywało, co oznacza, że ​​również przenumeruje klucze ...

Obejściem problemu jest ponowne utworzenie kluczy.

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

Aktualizacja 2: Zawsze zapominam, że jest też operator (pogrubioną czcionką, ponieważ naprawdę tego szukasz!: D)

$output = $array1 + $array2;

Wszystko to można zobaczyć na: http://php.net/manual/en/function.array-merge.php

KingCrunch
źródło
5
@KingCrunch - Mimo że liczby są cytowane w cudzysłowie, nieto klucze łańcuchowe, więc indeks nie zostanie zachowany. Przykład: ideone.com/I2NFT
Brendan Bullen
1
Naprawdę ... Najpierw chciałem porozmawiać o "błędzie", ale potem zauważyłem, że podręcznik mówi tylko o "klawiszach numerycznych", a nie o "klawiszach całkowitych". To trochę zagmatwane.
KingCrunch
+1 Zapomniałem o operatorze! Znakomity (pogrubioną czcionką!;))
Brendan Bullen,
3
Tak więc $array1 + $array2jest krótkie i wydajne rozwiązanie zamiast array_merge() - array_combine()kombinacji
Awan
2
OSTRZEŻENIE! dla tablic non-assoc lub jeśli tablice mają wspólne klucze$a + $b != array_merge($a, $b)
jmarceli
33

Powinieneś to wziąć pod uwagę $array1 + $array2 != $array2 + $array1

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

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

z $ tablica1 + $ tablica2

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

i $ tablica2 + $ tablica1

$array2 + $array1 = array(  
'11' => 'x1',  
'22' => 'x2',  
'33' => 'x2'  
);
inemanja
źródło
25

To działa:

$output = $array1 + $array2;
Michas
źródło
12
Nie polecałbym tego, ponieważ jego zachowanie jest bardzo nieintuicyjne, np.[1,2,3] + [4,5,6] == [1,2,3]
jchook
@jchook Co zatem Pan poleca?
Michas
Właśnie tego potrzebowałem, dzięki. Oto dlaczego: http_build_query(array_merge($array1, $array2))nie działa dla mnie, http_build_query($array1 + $array2)ale tak.
BarryMode
4

Aby to zrobić, możesz zapętlić jeden i dołączyć do drugiego:

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

?>

AKTUALIZACJA: KingCrunch wymyślił najlepsze rozwiązanie :print_r($array1+$array2);

Brendan Bullen
źródło
2

Jeśli używasz PHP 7.4 lub nowszego, możesz użyć operatora spreadu ...jako poniższych przykładów z Dokumentów 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]

Działa jak w JavaScript ES6.

Zobacz więcej na https://wiki.php.net/rfc/spread_operator_for_array .

Studentka nauk ścisłych
źródło
Nie dotyczy to pytania. OP ma klucze łańcuchowe dla tablicy (to nie działa z operatorem rozproszenia), a OP chce zachować klucze (operator rozproszenia wyrzuca klucze). Również OP nie chce duplikatów.
martti
Och, widzę twoje punkty. To prawda i masz rację. Czy możesz podać kod, który pomoże nam ulepszyć moją odpowiedź dla innych osób? Byłbym wdzięczny za Twój czas! Bardzo dziękuję za wskazanie wad mojej odpowiedzi.
Student of Science
Nie sądzę, aby operator rozprzestrzeniania był właściwym rozwiązaniem. Zamiast tego skorzystaj z podanej odpowiedzi$array1 + $array2
martti
Nie byłem tego świadomy! To znaczy, nie wiedziałem, że możemy to zrobić $ouput = $array1 + $array2. Teraz nauczyłem się czegoś nowego! Dziękuję Ci!
Student of Science
1

To działa:

$a = array(1 => 1, 2 => 2, 3 => 3);
$b = array(4 => 4, 5 => 5, 6 => 6);
$c = $a + $b;
print_r($c);
jeni
źródło
1

Ostrzeżenie! $ array1 + $ array2 nadpisuje klucze, więc moim rozwiązaniem (dla tablic wielowymiarowych) jest użycie array_unique ()

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

Ogłoszenie:

5.2.10+ Zmieniono domyślną wartość z sort_flagspowrotem na SORT_STRING.

5.2.9 Wartość domyślna to SORT_REGULAR.

5.2.8 - Wartość domyślna to SORT_STRING

Działa doskonale . Mam nadzieję, że to samo pomaga.

Norman Edance
źródło
1
array_merge()nie zachowuje jednak kluczy. Utworzona przez to tablica jest indeksowana do 0.
HPierce
@HPierce No cóż, w przypadku dodawania tablicy wielowymiarowej niektóre informacje zostaną utracone przy użyciu +. Spójrz na: PHPFiddle , $ b [0] zostanie utracone ...
Norman Edance
1

Nowy sposób na zrobienie tego z php7.4 to operator rozprzestrzeniania [...]

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

Operator spreadu powinien mieć lepszą wydajność niż array_merge

Istotną zaletą operatora Spread jest to, że obsługuje on wszystkie obiekty, przez które można przechodzić, podczas gdy funkcja array_merge obsługuje tylko tablice.

Shoaib Ahmed
źródło