/
Optymalizacja wydajności

Łączenie dużych tablic w PHP

06. 02. 2020

Często potrzebujemy połączyć wiele tablic razem, można to zrobić w bardzo elegancki sposób za pomocą funkcji `array_merge`:

$userIdsA = [1, 2, 3];
$userIdsB = [5, 6, 7];
// zwraca [1, 2, 3, 5, 6, 7].
$finalIds = array_merge($userIdsA, $userIdsB);

Funkcja array_merge łączy dwie tablice w jedną dużą tablicę. Jeśli dojdzie do kolizji kluczy, wygrywa wartość tablicy najbardziej wysuniętej na prawo.

Wielokrotne łączenie w pętli

Często jednak otrzymujemy tablicę tablic, która jest tworzona dopiero w pętli (na przykład z bazy danych, a następnie przepuszczana przez foreach), a więc nie znamy z góry liczby łączeń.

Naiwne rozwiązanie może wyglądać następująco:

$finalIds = [];
foreach ($users as $user) {
$finalIds = array_merge($finalIds, $user->someIds);
}

Takie rozwiązanie jest jednak bardzo nieefektywne z punktu widzenia procesora, ponieważ przy każdej iteracji musimy scalać tablice i iterować nad całą dużą tablicą.

Istnieje jednak proste rozwiązanie polegające na zmodyfikowaniu algorytmu scalania w taki sposób, aby dane były przeglądane tylko raz:

$finalIds = [];
foreach ($users as $user) {
$finalIds[] = $user->someIds;
}

W tym przypadku pole $finalIds wygeneruje nieco więcej danych, ale jest to wciąż mniejszy problem niż korzyść związana z oszczędnością czasu.

Samo scalanie zależy od wersji PHP, której używasz, a rozwiązuje się je za pomocą eleganckiego triku:

/* PHP 5.6 i starsze */
$finalIds = call_user_func_array('array_merge', $finalIds + [[]]);
/* PHP 5.6+ i nowsze */
$finalIds = array_merge([], ...$finalIds);
/* PHP 7.4+ i nowsze dla niepustych pól */
$finalIds = array_merge(...$finalIds);

W szczególności rozwiązanie array_merge(...$finalIds) wygląda bardzo interesująco, ponieważ wykorzystuje nową koncepcję PHP 7, w której można przekazać dynamiczną liczbę argumentów do funkcji, używając znaku trójki na początku. Proces scalania jest wtedy maksymalnie wydajny, a cała logika jest automatycznie obsługiwana wewnętrznie przez PHP.

Skrótowa notacja array_merge(...$finalIds) może być używana tylko dla niepustych tablic. Jeśli jest to tablica pusta, do funkcji nie jest przekazywany żaden argument i funkcja wyrzuca błąd Funkcja array_merge wywołana z 0 parametrami, wymagany co najmniej 1..

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
3.