Skip to content
Theory · Array functions · lesson 7 of 8

Merging, slicing and splitting

Three jobs are left for the cloakroom staff: combine two cloakrooms into one, hand out part of the items and hang up items that were brought in as one bundle.

Let's start with merging. If the items hang on numbered hooks, the second cloakroom's items go onto the next free hooks.

Name tags are harder: what if the tag 'color' is in both cloakrooms? PHP has two different answers to that:

PHP
<?php

$a = [1, 2];
$b = [3, 4];
echo json_encode(array_merge($a, $b)), "\n"; // [1,2,3,4]
echo json_encode([...$a, ...$b]), "\n"; // [1,2,3,4]
$defaults = ['color' => 'red', 'size' => 'M'];
$chosen = ['color' => 'blue'];
echo json_encode(array_merge($defaults, $chosen)), "\n"; // {"color":"blue","size":"M"}
echo json_encode($chosen + $defaults), "\n"; // {"color":"blue","size":"M"}
echo json_encode($defaults + $chosen), "\n"; // {"color":"red","size":"M"}

Three ways to merge arrays

array_merge

array_merge($a, $b) takes the elements of $a and then the elements of $b. It hands out integer keys again in order, so two lists join into one. On a repeated string key the right array wins: 'blue' from $chosen replaces 'red' from $defaults.

The + operator

$x + $y adds to the left array only the keys it does not have yet. A matching key stays with the left array, so $defaults + $chosen keeps 'red'. That gives a handy trick: $chosen + $defaults is the user's choice filled in with the default settings.

Unpacking with ...

The expression [...$a, ...$b] pours the elements of both arrays into a new list, like array_merge. With string keys it works the same way: since PHP 8.1 the right array wins on a repeated key.

Interviewers often ask how array_merge differs from +. The answer:

  • array_merge renumbers integer keys and gives a repeated string key to the right array;
  • + keeps every key of the left array and only adds the missing ones.

Slicing and cutting

A slice is a copy of part of an array. array_slice returns one, while array_splice does not copy the part but cuts it out:

PHP
$queue = ['ann', 'bob', 'cat', 'dan'];
$part = array_slice($queue, 1, 2);
echo implode(' ', $part), ' | ', count($queue), "\n"; // bob cat | 4
$cut = array_splice($queue, 1, 2);
echo implode(' ', $cut), ' | ', implode(' ', $queue), "\n"; // bob cat | ann dan
array_splice($queue, 1, 0, ['eve']);
echo implode(' ', $queue), "\n"; // ann eve dan

array_slice copies

array_slice($queue, 1, 2) returns a new array: start at position 1, counting from zero, and take 2 elements. The third argument is how many to take, not where to stop. The original array does not change: $queue still holds four names.

array_splice cuts

array_splice takes the array by reference, like sort. It cuts a piece out of $queue itself and returns what it cut, and it renumbers the integer keys of the remaining elements.

As a fourth argument you can pass what to insert in the freed space. With a length of 0 it removes nothing and only inserts: that is how 'eve' ended up between 'ann' and 'dan'.

This is where the cloakroom picture falls short. A real attendant cannot hand out an item and leave it on the hook at the same time. array_slice does exactly that: it hands out copies, and the items stay where they are.

From a string to an array and back

A string with separators is that very bundle. explode unties it and hangs the pieces on hooks, and implode, which you already know, joins them back:

PHP
$csv = 'tea,milk,,bread';
$items = explode(',', $csv);
echo count($items), "\n"; // 4
var_dump($items[2]); // string(0) ""
echo implode(' + ', $items), "\n"; // tea + milk +  + bread
echo implode(' ', str_split('abcdef', 2)), "\n"; // ab cd ef

Let's go through it line by line:

  1. explode(',', $csv) cuts the string at every comma. The separator comes first, the string second.
  2. There is nothing between the two commas in a row, and explode returns that empty piece as an element of its own. So there are four parts, and $items[2] is an empty string.
  3. implode joins the parts back, and where the empty piece was you see two spaces in a row.
  4. str_split('abcdef', 2) cuts the string into pieces of two bytes; for Latin letters a byte is one character, so the result here is ab cd ef. It can cut a Cyrillic letter in half: for Cyrillic there is mb_str_split.

Common mistake

Two lists were added with +:

PHP
$week = ['mon', 'tue'];
$weekend = ['sat', 'sun'];
$days = $week + $weekend; // ✗
echo implode(' ', $days), "\n";

The program prints mon tue, and PHP shows no message. Both lists have the keys 0 and 1, and + adds only keys the left array lacks—there were none. The fix is array_merge($week, $weekend) or [...$week, ...$weekend]: both give mon tue sat sun.

Key points

  • array_merge and [...$a, ...$b] append the elements and renumber the integer keys; on a repeated string key the right array wins.
  • + keeps every key of the left array and adds only the missing ones, so two lists do not join with +.
  • array_slice returns a copy of a piece and leaves the source alone, while array_splice cuts the piece out of the array itself and returns what it cut.
  • explode cuts a string at the separator and keeps empty pieces, and implode joins an array back into a string.