Kawałek Kodu

Bycie swatką lub swatem w życiu na pierwszy rzut oka wydaje się prostym i wdzięcznym zajęciem. Jeśli para ma się ku sobie, sprawa załatwiona, gorzej jeśli dwa "elementy" nijak nie chcą się zejść.

Ostatnio przykleiło się do mnie podobne zadanie, ale na szczęście nie w życiu, choć i tu perturbacje były spore. Miałem potrzebę połączenia dwóch tablic, z których jedna z nich zawierała elementy na pozycjach nieparzystych, a druga na pozycjach parzystych. Problem wydaje się prosty, ale celem było otrzymanie tablicy, w której kolejno na pozycje nieprzyste wpadają elementy z tablicy "nieparzystej", a na pozycje parzyste elementy z tablicy "parzystej". No i nadal problem nie wydaje się skomplikowany...
Jednak jest jeszcze jedna kluczowa (sic!) kwestia, mianowcie obydwie tablice były asocjacyjne, a klucze i kolejność występowania elementów w każdej z nich musiała być odwzorowana w tabeli docelowej.

Podsumowując, założenia są następujące:

  • mamy dwie tablice źródłowe,
  • obydwie tablice są asocjacyjne,
  • obydwie tablice są tej samej długości,
  • na pozycjach, które nas nie interesują mogą wystąpić dowolne wartości,
  • klucze mają być zachowane,
  • kolejność ma być zachowana.

Przykładowe tablice źródłowe:

$array1 = [23 => 'a', 14 => null, 1 => 'b', 56 => ''];
$array2 = [2 => 'xxx', 6 => 'c', 11 => null, 'o1' => 'd'];

A docelowa ma wyglądać tak:

$array = [23 => 'a', 6 => 'c', 1 => 'b', 'o1' => 'd'];

Spróbujmy tak:

$array = array();

for ($i = 0; $i < count($array1); $i += 2) {
    array_push($array, array_slice($array1, $i, 1, true), array_slice($array2, $i + 1, 1, true));
}

print_r($array);

No i źle:

Array
(
    [0] => Array
        (
            [23] => a
        )

    [1] => Array
        (
            [6] => c
        )

    [2] => Array
        (
            [1] => b
        )

    [3] => Array
        (
            [o1] => d
        )

)

Otrzymaliśmy tablicę jednoelementowych tablic, ponieważ array_slice zwraca nie wartość tablicy, lecz jej element (wycinek) wraz z kluczem. Jednak gdyby ta funkcja zwracała wartość i tak by się nie przydała, bo potrzebny nam jest jeszcze klucz.

A tak?

$array = array();

for ($i = 0; $i < count($array1); $i += 2) {
    $array = array_merge($array, array_slice($array1, $i, 1, true), array_slice($array2, $i + 1, 1, true));
}
print_r($array);

Nic z tego...

Array
(
    [0] => a
    [1] => c
    [2] => b
    [o1] => d
)

Kolejność prawidłowa, tablica jest jednowymiarowa, ale niektóre klucze zgubione. Dzieje się tak dlatego, ponieważ funkcja array_merge w przypadku kluczy numerycznych reindeksuje je nadając kolejne indeksy od 0.

Szkoda...ale zaraz, zaraz. Była sobie jeszcze inna metoda łączenia tablic, coś w rodzaju dodawania...

$array = array();

for ($i = 0; $i < count($array1); $i += 2) {
    $array += array_slice($array1, $i, 1, true) + array_slice($array2, $i + 1, 1, true);
}
print_r($array);

A wynik?

Array
(
    [23] => a
    [6] => c
    [1] => b
    [o1] => d
)

Bingo! Kolejność zachowana, elementy jak trzeba i klucze są!

 

Przydatne linki:
Operatory tablicowe (+/union)
Funkcja array_merge
Funkcja array_slice
Funkcja array_push