PHP: scalić dwie tablice, zachowując klucze zamiast reindeksowania?

255

Jak scalić dwie tablice (jedną z ciągiem => parami wartości, a drugą z int => parami wartości), zachowując klucze ciąg / int? Żadne z nich nigdy się nie nakłada (ponieważ jeden ma tylko łańcuchy, a drugi tylko liczby całkowite).

Oto mój obecny kod (który nie działa, ponieważ array_merge ponownie indeksuje tablicę za pomocą kluczy całkowitych):

// get all id vars by combining the static and dynamic
$staticIdentifications = array(
 Users::userID => "USERID",
 Users::username => "USERNAME"
);
// get the dynamic vars, formatted: varID => varName
$companyVarIdentifications = CompanyVars::getIdentificationVarsFriendly($_SESSION['companyID']);
// merge the static and dynamic vars (*** BUT KEEP THE INT INDICES ***)
$idVars = array_merge($staticIdentifications, $companyVarIdentifications);
Garrett
źródło
1
To dziwne: według strony dokumentu PHP, array_merge nie powinien tego robić. Czy klucze łańcuchowe są w rzeczywistości reprezentacjami liczb całkowitych?
owenmarshall
array_merge ponownie indeksuje moją drugą tablicę. to znaczy. zmienia tablicę z array( 123 => "VALUE123" )naarray( 0 => "VALUE123" )
Garrett,
hmm, to interesujące. Podejrzewam, że dokumentacja PHP może być nieco niejasna w tej kwestii. Mówi, co się stanie, jeśli wszystkie tablice mają klawisze numeryczne, ale nie mówi konkretnie, co się stanie, jeśli nie będą.
Steven Oxley,
może nie 2 lata temu. Ale w 2012 r. Dokumentacja w tej kwestii jest krystalicznie czysta.
cartbeforehorse
W rzeczywistości dokumentacja wciąż nie jest krystalicznie czysta. „Numeryczne” faktycznie zawiera ciąg ze wszystkimi cyframi (PHP 5.3.3). assert(array(0=>0,1=>1) === array_merge(array('9'=>0), array('9'=>1)))
Bob Stein

Odpowiedzi:

557

Możesz po prostu „dodać” tablice:

>> $a = array(1, 2, 3);
array (
  0 => 1,
  1 => 2,
  2 => 3,
)
>> $b = array("a" => 1, "b" => 2, "c" => 3)
array (
  'a' => 1,
  'b' => 2,
  'c' => 3,
)
>> $a + $b
array (
  0 => 1,
  1 => 2,
  2 => 3,
  'a' => 1,
  'b' => 2,
  'c' => 3,
)
SirDarius
źródło
44
Bądź z tym BARDZO ostrożny! Operator + nie jest dodatkiem, to związek. Jeśli klucze się nie pokrywają, wszystko jest w porządku, ale jeśli tak ...
GordonM
3
Po prostu łał - zaoszczędziłeś mi wiadra linii kodu, prawie trzy lata później.
Stephen O'Flynn
85
Na wypadek, gdyby ktoś zastanawiał się „co, jeśli się pokrywają?” : php.net: „Operator + zwraca tablicę po prawej stronie dołączoną do tablicy po lewej stronie; w przypadku kluczy istniejących w obu tablicach zostaną użyte elementy z tablicy po lewej stronie, a pasujące elementy z prawej tablica ręczna zostanie zignorowana. "
Flion 18.09.13
2
@Flion to bardziej skomplikowane. Używając „+”, właśnie dodałem dwie pod-tablice z elementem ze wspólnym kluczem i podkluczem: wartości zostały dodane! 100000 => tablica (rozmiar = 3) 1 => int 128 2 => int 56 3 => int 7 + 100000 => tablica (rozmiar = 1) 2 => int 30 Wynik: 100000 => tablica (rozmiar = 3) 1 => int 128 2 => int 86 3 => int 7 Zasadniczo dodanie [2 => 56] + [2 => 30] nie zastąpiło wartości, ale ją dodało i stało się [2 => 86]
Dario Fumagalli
1
@DarioFumagalli Nie wiem, czy się mylę, czy zmieniłem to dopiero od 2016 roku, ale w tym momencie operacja się print_r([2 => 56] + [2 => 30]);kończy Array ( [2] => 56 ). Tak więc utrzymuje lewą stronę zgodnie z opisem. To jest jak z PHP 7.1.19, działa na repl.it .
Charles Wood
62

Biorąc pod uwagę, że masz

$replaced = array('1' => 'value1', '4' => 'value4');
$replacement = array('4' => 'value2', '6' => 'value3');

Wykonanie $merge = $replacement + $replaced;spowoduje:

Array('4' => 'value2', '6' => 'value3', '1' => 'value1');

Pierwsza tablica z sumy będzie miała wartości na końcowym wyjściu.

Wykonanie $merge = $replaced + $replacement;spowoduje:

Array('1' => 'value1', '4' => 'value4', '6' => 'value3');
CRK
źródło
[[thumbsup]] na ten temat
Jhourlad Estrella,
21
Podsumowując, dodając 2 tablice, wartości z pierwszego zastępują wartości z drugiego.
Dziamid
1
Myślałem, że drugi zastąpi pierwszy. :)
Asim KT
1
Dokładnie. Dlatego nie mogłem użyć $allValues += $newValues;.
MarthyM,
Wykonanie $merge = $replacement + $replaced;spowoduje:Array ( [4] => value2 [6] => value3 [1] => value1 )
Chandan Sharma
24

Chociaż to pytanie jest dość stare, chcę tylko dodać kolejną możliwość wykonania scalenia przy zachowaniu kluczy.

Oprócz dodawania klucza / wartości do istniejących tablic za pomocą +znaku, który możesz zrobić array_replace.

$a = array('foo' => 'bar', 'some' => 'string');
$b = array(42 => 'answer to the life and everything', 1337 => 'leet');

$merged = array_replace($a, $b);

Wynik będzie:

Array
(
  [foo] => bar
  [some] => string
  [42] => answer to the life and everything
  [1337] => leet
)

Te same klucze zostaną zastąpione przez drugą tablicę.
Istnieje również opcja array_replace_recursive, która robi to również dla podrzędnych.

Przykład na żywo na 3v4l.org

Danopz
źródło
3

Dwie tablice można łatwo dodać lub połączyć bez zmiany pierwotnego indeksowania przez operatora + . Będzie to bardzo pomocne w rozwijaniu laravela i rozwijania programu do znakowania kodu.

 $empty_option = array(
         ''=>'Select Option'
          );

 $option_list = array(
          1=>'Red',
          2=>'White',
          3=>'Green',
         );

  $arr_option = $empty_option + $option_list;

Dane wyjściowe będą:

$arr_option = array(
   ''=>'Select Option'
   1=>'Red',
   2=>'White',
   3=>'Green',
 );
Amba Patel
źródło
1

Wypróbuj funkcje array_replace_recursive lub array_replace

$a = array('userID' => 1, 'username'=> 2);
array (
  userID => 1,
  username => 2
)
$b = array('userID' => 1, 'companyID' => 3);
array (
  'userID' => 1,
  'companyID' => 3
)
$c = array_replace_recursive($a,$b);
array (
  userID => 1,
  username => 2,
  companyID => 3
)

http://php.net/manual/en/function.array-replace-recursive.php

zdenek
źródło