+ operator dla tablicy w PHP?


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

Co +oznacza tablica w PHP?


5
Zauważyłem, że twoje pytanie brzmiało, +=a odpowiedź zaakceptowana +. Z moich testów wydają się one zachowywać tak samo.
user151841,

7
Dokumentacji podsumowuje to całkiem dobrze
artfulrobot


@RobbieAverill - to pytanie, do którego odnosi się to pytanie referencyjne. Więc jeśli cokolwiek to pytanie referencyjne jest duplikatem
icc97

2
Czy ktoś jeszcze jest nieco przerażony, że tak fundamentalna rzecz jak konkatenacja macierzy musi zostać wykonana array_merge? To tak, jakby tablice były domyślnie tablicami asocjacyjnymi, a tablice numeryczne są obywatelami drugiej kategorii.
icc97

Odpowiedzi:


271

Cytowanie z podręcznika PHP dotyczącego operatorów języków

Operator + zwraca tablicę po prawej stronie dołączoną do tablicy po lewej stronie; w przypadku kluczy istniejących w obu tablicach użyte zostaną elementy z tablicy po lewej stronie, a pasujące elementy z tablicy po prawej stronie zostaną zignorowane.

Jeśli tak

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

print_r($array1 + $array2);

Dostaniesz

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

Zatem logika +jest odpowiednikiem następującego fragmentu:

$union = $array1;

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

Jeśli jesteś zainteresowany szczegółami implementacji na poziomie C, przejdź do


Zauważ, że +różni się to od sposobu array_merge()łączenia tablic:

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

dałbym ci

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
)

Zobacz połączone strony, aby uzyskać więcej przykładów.


1
@Pacerier PHP produkowany przez php.net nie ma formalnej specyfikacji, ale zarówno +i jak i array_mergecall zend_hash_mergepod maską. Jest to również oczekiwane, ponieważ w PHP tablice są implementowane jako uporządkowane mapy skrótów.
biskup

1
@Pacerier Dokumenty internetowe php.net są najbliższym zapisem specyfikacji, ale IMO te dokumenty nie są zgodne z prawdziwą specyfikacją: po pierwsze, są aktualizowane po napisaniu kodu; po drugie, nie są napisane, aby objąć każde specjalne użycie.
biskup

14
Zachowanie PHP +i array_mergejest przewrotny i nieintuicyjne. Są odwrotne od tego, co zwykłe angielskie czytanie intuicyjnie powiedziałoby ci, że wystarczy „dodać” lub „scalić” tablice. Inne języki / biblioteki używają +do łączenia list (np. W Pythonie) i funkcji „scalania”, aby dodać pary klucz / wartość z jednego obiektu do drugiego (np. W lodash). Jednak w PHP jest odwrotnie; array_mergemoże być używany do łączenia tablic podobnych do list, ale +nie może. W przeciwieństwie array_merge, +zawsze wykonuje operację, która będzie nazywana „scalania” w jakimkolwiek innym języku.
Mark Amery

1
@ icc97 są rzeczywiście tylko HashMaps. Zobacz nikic.github.io/2014/12/22/…
Gordon

2
Próbowałem zgłosić błąd, aby sprawdzić, czy array_concatmożna utworzyć alias array_merge.
icc97

18

Najlepszy przykład, jaki znalazłem, używając tego, to tablica konfiguracji.

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

$config = $user_vars + $default_vars;

Jak $default_varssugeruje, jest to tablica wartości domyślnych. $user_varsTablica zastąpi wartości określone w $default_vars. Wszelkie brakujące wartości $user_varssą teraz zmiennymi domyślnymi$default_vars .

Byłoby to print_r:

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

Mam nadzieję, że to pomoże!


6

Ten operator przyjmuje sumę dwóch tablic (tak samo jak array_merge, tyle że w przypadku array_merge duplikaty kluczy są nadpisywane).

Dokumentacja dla operatorów macierzy znajduje się tutaj .


1
Słowo ostrzeżenia dla początkujących tutaj, wynik operacji jest zerowy, jeśli którakolwiek z tablic jest pusta . Niektórzy mogą nie przejmować się tym założeniem, ponieważ jest to operacja unii, wynikiem będzie odpowiednia tablica (nie-null), jeśli jedna z nich ma wartość null. Jest to prawdą, jeśli jedna z tablic jest pustą tablicą.
Sandeepan Nath,

Tak więc, myślę, że jako dobrą praktykę powinniśmy inicjować tablice wejściowe jako puste tablice. Co mówicie
Sandeepan Nath,

5

Ostrożnie z klawiszami numerycznymi, jeśli powinny zostać zachowane lub jeśli nie chcesz niczego stracić

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

unia

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

łączyć

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

3

+Operator daje takie same wyniki jak array_replace () . Ponieważ jednak argumenty operatora są odwrócone, kolejność wynikowej tablicy może być również inna.

Rozwijanie innego przykładu z tej strony:

$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

wyjścia:

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
)

Czy +specyfikacja gwarantuje kolejność ? Co array_replace?
Pacerier

1
  1. Operacja Array plus traktuje całą tablicę jako tablicę assoc.
  2. W przypadku konfliktu kluczy podczas plusa zachowana zostanie lewa (poprzednia) wartość

Podaję poniższy kod, aby wszystko było jasne.

$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;
}

@ Uruchomienie kodu Tamlyn wydaje się dowodzić, że twoje twierdzenie „tablica plus operacja traktuje całą tablicę jako tablicę assoc” jest błędne.
Pacerier

@Pacerier ten klucz może być również liczbą całkowitą.
Hitesh


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

Tablica ([0] => przykład [1] => test)


1
Wątek ten kilkakrotnie wspomina, że ​​tablica_merge () NIE jest przystająca.
doublejosh

@doublejosh, „przystający”? Znaczenie?
Pacerier

1
One nie są takie same.
doublejosh
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.