PHP Array Functions

Chapter 32 42 mins

Learning outcomes:

  1. Adding/removing elements using array_unshift(), array_shift(), array_splice()
  2. Slicing an array using array_slice()
  3. Reversing an array using array_reverse()
  4. Mapping (array_map()), filtering (array_filter()) and reducing (array_reduce()) arrays
  5. Filling arrays with values using array_fill()
  6. Joining array elements together using implode()
  7. Exploring more array functions in PHP

Introduction

PHP comes equipped with over fifty functions to work with arrays, allowing us to do such diverse things as computing the intersection of arrays; executing functional ideas such as 'map' and 'reduce'; rearranging elements in a random order; sorting arrays; and much more.

We've already explored a handful of functions in the preceding chapters of this unit.

In particular, we saw in_array() and array_search(), and array_key_exists() in PHP Arrays — Basics; and all the sorting-related functions such as sort(), rsort(), ksort(), asort(), usort(), in the PHP Arrays — Sorting chapter.

Now in this chapter, our goal is to unravel some other frequently used array functions in PHP. We'll see how to add/remove elements from an array from the start, end or any arbitrary position; how to execute functional concepts such as 'map' and 'reduce'; how to slice arrays; how to randomly shuffle arrays; and a lot more suchlike.

Let's begin the exploration.

Adding/removing elements

We'll start with the basic idea of adding and removing elements from an array.

There are 3 distinctions that we can make in regards to the position where such array functions operate:

  1. array_push() and array_pop() work on the end of the array.
  2. array_unshift() and array_shift() work on the start of the array.
  3. array_splice() works at any given position.

We've already seen array_push() and array_pop() in action in PHP Arrays — Basics, and so we won't be going over them again. Over to the other three functions...

array_unshift() and array_shift()

The array_unshift() function is used to add an element, or a group of elements, at the start of an array.

Here's its syntax:

array_unshift($array, $element_1, $element_2, ...)

Akin to array_push(), its first argument is the concerned array while the subsequent arguments each specifies an item to add. Note that the order of items in the invocation of array_unshift() is the same as the order of the items once they've been added to the array.

In contrast to this, array_shift() removes the first element from the array and shifts the entire following sequence of elements down by one position.

Just like array_pop(), as shown below,

array_shift($array)

array_shift() takes no arguments and returns back the element removed, or NULL if the given array is empty.

Shown below is an example, demonstrating the usage of array_unshift() and array_shift():

<?php

$nums = [5, -9, 10, 50];

array_unshift($nums, 100);
print_r($nums);

$element = array_shift($nums);
echo "Removed $element\n";
print_r($nums);
Array ( [0] => 100 [1] => 5 [2] => -9 [3] => 10 [4] => 50 ) Removed 100 Array ( [0] => 5 [1] => -9 [2] => 10 [3] => 50 )

First, we call array_unshift() to add an element, 100, at the start of $nums, and then print the array. Next up, we call array_shift() to remove that element from the array, printing the removed element and then configuration of the array thereafter.

If you can remember, JavaScript has array methods with a similar nomenclature, performing similar utilities. That is, we have push(), pop(), unshift() and shift().

array_splice()

The four functions array_push(), array_pop(), array_unshift() and array_shift() all work on fixed positions, i.e. the start or the end of an array, respectively.

However, sometimes we might want to perform addition/removal at any arbitrary position. For instance, we might want to add an element at index 3, or possibly remove the twentieth element from an array of over a hundred elements.

How could we accomplish this? Well, array_splice() is just what we need.

array_splice() is used to add and/or remove a given element, or a set of elements, from an arbitrary position.

Shown below is its syntax:

array_splice(&$array, $offset, $length = null, $replacement = [])

The first argument, as before, is the array to operate on; $offset specifies the index where to start the addition/removal; $length specifies the number of elements to remove from that point onwards; and $replacement defines the replacements.

If we have more that one replacement (for example, when we remove two elements and want to replace them with two new elements), $replacements ought to be an array specifying the replacing items.

array_splice() returns back an array containing the items removed from the array on which the function was invoked.

Moreover, after array_splice() removes and then adds back elements to an array, starting at a given position, it normalizes its indexes following that position. For example, if four elements are removed and only one is added, at index 1, each subsequent element's index is reduced by 3.

The array_splice() function in PHP works pretty much like the splice() array method in JavaScript.

Let's consider a couple of examples to see how array_splice() works.

In the following code, we try to remove the second element from $nums using array_splice(), saving its return value in a variable $removed_nums, and then print both these arrays:

<?php

$nums = [1, 50, -6, -20, 22];
$removed_nums = array_splice($nums, 1, 1);

echo "\$nums:\n";
print_r($nums);

echo "\n\$removed_nums:\n";
print_r($removed_nums);
$nums: Array ( [0] => 1 [1] => -6 [2] => -20 [3] => 22 ) $removed_nums: Array ( [0] => 50 )

As can be seen by the output, the second element, 50, has indeed been removed from $nums and the indexes have been normalized after the removal.

Let's consider another example using this same code template:

<?php

$nums = [1, 50, -6, -20, 22];
$removed_nums = array_splice($nums, 2, 2, 10000);

echo "\$nums:\n";
print_r($nums);

echo "\n\$removed_nums:\n";
print_r($removed_nums);

This time, we aim to remove two elements (the third argument 2), starting at index 2 (the second argument 2), and put just one element, 10000 in place of it (the last argument 10000).

$nums: Array ( [0] => 1 [1] => 50 [2] => 10000 [3] => 22 ) $removed_nums: Array ( [0] => -6 [1] => -20 )

The $removed_nums array here clearly shows that the two desired elements have been removed from $nums, i.e. -6 and -20.

Let's now test your understanding of array_splice().

What would $nums be after the execution of the following code?

<?php

$nums = [1, 50, -6, -20, 22];
array_splice($nums, 0, 1);
  • [50, -6, -20, 22]
  • [1, 50, -6, -20, 22]
  • [1, 1, 50, -6, -20, 22]
  • [0, 1, 1, 50, -6, -20, 22]

What would $nums be after the execution of the following code?

<?php

$nums = [1, 50, -6, -20, 22];
array_splice($nums, 3, 0, 10000);
  • [1, 50, -6, -20, 22]
  • [1, 50, -6, -20, 10000, 22]
  • [1, 50, -6, 10000, -20, 22]
  • [1, 50, -6, -20, 0, 10000, 22]

Slicing an array

Extracting slices, i.e. subarrays, out of arrays is a fairly common routine in programming. In PHP, we use the array_slice() function to slice an array.

Following is its syntax:

array_slice($array, $start, $length = null, $preserve_keys = false)
  • $array is the array to slice.
  • $start is an integer that specifies the position where to start the slicing.
  • $length is an integer specifying the length of the slice. If omitted, the entire subsequent array is extracted into a slice from the given starting position.
  • $preserve_keys specifies whether or not the keys should be preserved in the slice.

If $length is a negative integer, that many elements are omitted from the array's end in the sliced subarray.

array_slice() returns a new array which is a subarray of the underying array.

Consider the following example:

<?php

$nums = [10, 20, 30, 40, 50];
$nums_slice = array_slice($nums, 0, 4);

print_r($nums_slice);
Array ( [0] => 10 [1] => 20 [2] => 30 [3] => 40 )

Here we make a slice of $nums, starting at index 0 and having a total of 4 elements in it. This gives the array [10, 20, 30, 40].

Now let's try tweaking the arguments to the function a little bit:

<?php

$nums = [10, 20, 30, 40, 50];
$nums_slice = array_slice($nums, 1, 3);

print_r($nums_slice);
Array ( [0] => 20 [1] => 30 [2] => 40 )

Here we're slicing $nums starting at index 1 and containing a total of 3 elements. Not that difficult.

At this point, it's worthwhile incorporating the $preserve_keys parameter to see how it affects the result:

<?php

$nums = [10, 20, 30, 40, 50];
$nums_slice = array_slice($nums, 1, 3, true);

print_r($nums_slice);
Array ( [1] => 20 [2] => 30 [3] => 40 )

The values in the sliced array are obviously the same since the second and third arguments to array_slice() are the same. What's different, however, is the set of keys of the sliced array.

By virtue of the fourth, $preserve_keys, argument being true here, the keys are preserved as elements are extracted out from $nums into the sliced array.

Let's now try passing in a negative integer as $length:

<?php

$nums = [10, 20, 30, 40, 50];
$nums_slice = array_slice($nums, 1, -1);

print_r($nums_slice);
Array ( [0] => 20 [1] => 30 [2] => 40 )

As stated above, a negative integer means that the slice would leave off that many elements from the end of the array; in this case, -1 means that 1 element would be left off from the end of $nums.

If you're familiar with Python or JavaScript, you'll have a different sense of slicing that's apparently not present in PHP's array_slice() function, although it could be replicated very easily. This is discussed as follows.

Slicing from starting index to ending index

In programming languages such as Python and JavaScript, slicing is a supported operation just as it is in PHP. However, the way slicing happens is a little bit different.

To be precise, we still begin with a starting index but instead of providing the length of the slice, as in array_slice(), we provide the ending index for the slice and that is exclusive (it isn't included in the slice).

For example, here's a snippet from JavaScript:

var nums = [10, 20, 30, 40, 50];
var numsSlice = nums.slice(1, 4); // [20, 30, 40]

The first argument of the slice() method, 1, specifies the starting position (inclusive) of the slice, while the second argument, 4, specifies the ending position (exclusive). The result is the array [20, 30, 40].

In PHP, if we do the same, we get a different result and that's because the third argument doesn't specify the ending position for the slice; it instead specifies the length of the slice:

<?php

$nums = [10, 20, 30, 40, 50];
$nums_slice = array_slice($nums, 1, 4);

print_r($nums_slice);
Array ( [0] => 20 [1] => 30 [2] => 40 [3] => 50 )

The good news is that if we really want the behavior of slicing as is used in JavaScript (and even Python), we can do a simple computation.

That is, to subtract the ending position (exclusive) from the starting position to determine the length of the slice.

Do keep in mind that this approach only holds as long as the given ending position is a positive integer. For negative ending indices, we ought to bring in more handling code.

So, for instance, going with our old example of slicing from position 1 to 4 (exclusive), we'd do the following:

<?php

$nums = [10, 20, 30, 40, 50];
$nums_slice = array_slice($nums, 1, 4 - 1);

print_r($nums_slice);
Array ( [0] => 20 [1] => 30 [2] => 40 )

Voila!

Don't slice to copy arrays in PHP!

In some programming languages, the array slice operation is often used to copy an array. In PHP, as you know, we can do this using another much simpler technique, that is to assign the array to another variable.

So, use array_slice() in PHP whenever you really need to extract a proper subarray out of an array ('proper' means any subarray but the one that's the same as the original array).

Do NOT use array_slice() to merely copy an array! This is not about performance or efficiency; it's about refraining from using something when there exists a better and much simpler way to do the same thing.

Reversing an array

The array_reverse() function is used to reverse the order of elements of an array. Surprisingly, the function doesn't modify the original array, but instead returns a new array with elements in reverse order.

Below shown is array_reverse()'s syntax:

array_reverse($array, $preserve_keys = false)

As in array_slice(), the $preserve_keys parameter can be used to keep the key-value pairs intact after the reversal.

Let's consider a quick example.

In the following code, we sort the $nums array in descending order by first sorting it in ascending order via sort() and then reversing the sorted array using array_reverse():

<?php

$nums = [-5, 9, 3, 50, 0];
sort($nums);
$nums = array_reverse($nums);

print_r($nums);
Array ( [0] => 50 [1] => 9 [2] => 3 [3] => 0 [4] => -5 )

Notice the assignment statement in line 5 — this is utmost important because, as stated earlier, array_reverse() doesn't not modfiy the original array.

To learn more about how sort() works, refer to PHP Array Sorting.

Let's spice this example up with a teaspoon of $preserve_keys:

<?php

$nums = [-5, 9, 3, 50, 0];
sort($nums);
$nums = array_reverse($nums, true); print_r($nums);
Array ( [4] => 50 [3] => 9 [2] => 3 [1] => 0 [0] => -5 )

As you can see, this time the key-value associations are kept intact following the reversal operation, all thanks to $preserve_keys being true.

Maping, filtering and reducing arrays

Map, filter and reduce are operations common in the functional programming paradigm. They abstract away a lot of the control flow complexity in iterating over an array and executing certain code.

Map refers to creating a new array out of an existing array by mapping each element in the array to a given value. Filter refers to filtering out elements from an array based on a predicate function. Reduce is to reduce an array to a single value, aggregating all of its items based on an aggregating function.

The 'functional' aspect of all three of these functions is that they return new arrays — which is reminiscent of the fact that they treat the input array as immutable data — and that they don't perform any side effects, i.e. any changes to the global context.

Like many modern mainstream languages, PHP provides array functions to accomplish all three of these key operations. They are array_map(), array_filter() and array_reduce().

Let's see the functions in action.

array_map()

The array_map() function is used to obtain a new array based on an existing array and a mapping function.

Here's its syntax:

array_map($mapping_fx, $array);

As an elementary example, suppose we have a list of some arbitrary integers, as shown below:

<?php

$nums = [10, 12, -5, -3, 0];

What we want is to create a new array using this array of numbers by squaring each element. For instance, -5 should become 25, 12 should becomes 144, and so on.

With the help of array_map(), this is really easy. First, we ought to construct the mapping function.

The mapping function takes, as argument, each element of the underlying array and then returns a value which should be used in the mapped array. In simple words, we lay out the mapping rule in the mapping function.

Coming back to our example, our mapping rule is to square each element of $nums. Henceforth, our mapping function, let's call it to_square(), would look as follows:

function to_square($num) {
   return $num ** 2;
}

With this done, now let's get to the invocation of array_map():

<?php

function to_square($num) {
   return $num ** 2;
}

$nums = [10, 12, -5, -3, 0];

$squares = array_map('to_square', $nums);
print_r($squares);
Array ( [0] => 100 [1] => 144 [2] => 25 [3] => 9 [4] => 0 )

Simple, wasn't this?

Let's consider another example.

Say we have the following array of words,

<?php

$words = ['as', 'hello', 'for'];

and wish to obtain an array of the lengths of each of these words.

Well, great. This is the very purpose of array_map():

<?php

function to_length($word) {
   return strlen($word);
}

$words = ['as', 'hello', 'for'];

$lengths = array_map('to_length', $words);
print_r($lengths);
Array ( [0] => 2 [1] => 5 [2] => 3 )

And we're done.

array_filter()

The second function to consider it array_filter().

As per the name, array_filter() is meant to literally 'filter' out elements from an array based on a given predicate.

A predicate is basically a function that takes in a value and returns back a Boolean.

In the case of array_filter(), the predicate function takes in a given element of the underlying array, and specifies whether the given element should be included in the filtered array or not. Only if the predicate's condition is true is the element considered in the filtered array; otherwise, it's thrown away.

Syntactically, here's how array_filter() looks:

array_filter($array, $filter_fx = null, $mode = 0)

$array is the array to filter elements from; $filter_fx is the filtering function; and $mode specifies what argument(s) would the filter function get, i.e. the value only, the key only, or both.

The possible values for $mode are the following constants:

  • ARRAY_FILTER_USE_KEY — pass just the key of an element to the filter function.
  • ARRAY_FILTER_USE_BOTH — pass both the key and the value of an element, in this order, to the filter function.

Let's consider a simple example of using array_filter().

Suppose we have the following array of some common programming languages and want to only consider those that begin with the letter 'P':

<?php

$langs = [
   'Python', 'Go', 'PHP', 'Perl', 'JavaScript', 'C#', 'Powershell', 'Bash'
];

First, let's design the predicate function. We want to let in only those words that begin with a 'P', likewise our condition could be laid out as follows, utilizing the str_starts_with() function:

function starts_with_p($lang) {
   return str_starts_with($lang, 'P');
}

With this done, here's how to call array_filter() in order to perform the filtration:

<?php

function starts_with_p($lang) {
   return str_starts_with($lang, 'P');
}

$langs = [
   'Python', 'Go', 'PHP', 'Perl', 'JavaScript', 'C#', 'Powershell', 'Bash'
];

$p_langs = array_filter($langs, 'starts_with_p');
print_r($p_langs);

The first argument to the function is $langs, as we need to filter elements from it, whereas the second argument is 'starts_with_p', specifying the name of the function to use for the filtering.

Following is the output produced by this code:

Array ( [0] => Python [2] => PHP [3] => Perl [6] => Powershell )

Notice how the keys have been preserved in the filtered array. If we want to let go of these preservations, we can use the array_values() function to reindex the result.

Basically array_values() just extracts out all the values from an array and dumps them into a new indexed array.

Here's the code above rewritten with an additional processing of array_values() before storing a value in the $p_langs variable:

<?php

function starts_with_p($lang) {
   return str_starts_with($lang, 'P');
}

$langs = [
   'Python', 'Go', 'PHP', 'Perl', 'JavaScript', 'C#', 'Powershell', 'Bash'
];

$p_langs = array_values(array_filter($langs, 'starts_with_p'));
print_r($p_langs);
Array ( [0] => Python [1] => PHP [2] => Perl [3] => Powershell )

Perfect!

array_reduce()

Another functional array function that we have in PHP is array_reduce().

array_reduce() is meant to aggregate all the items of an array together and reduce them down to a single value, hence the name 'reduce.'

The way array_reduce() works is as follows:

  • We provide it with an array to reduce and a reduction function (also known as an aggregate function).
  • The function keeps track of an internal variable that represents the return value of the function. It's initialized to whatever value we provide when calling array_reduce().
  • As iteration progresses over the given array, each element is passed to the reduction function along with the current aggregate value.
  • The function is meant to return the new aggregate value, which then replaced the internal variable managed by array_reduce().
  • When iteration completes, the value of this variable is returned.

Conceptually, as you'd agree this all is fairly simple to understand.

Let's now see the syntax of array_reduce():

array_reduce($array, $reduction_fx, $initial = null)

$array is the array to reduce; $reduction_fx is the reduction function; and $initial is the starting value of the internal aggregate variable.

As stated before, array_reduce() returns this aggregate variable at the point of its completion.

Time for an example.

Suppose we have an array containing some words, as follows,

<?php

$words = ['as', 'hello', 'for'];

and want to determine the length of all them added together.

For example, in the array, the first string's length is 2, the second one's is 5, and the third one's is 3, so the answer we're looking for is 10 (2 + 5 + 3).

Well, this sounds like a great opportunity for array_reduce() to showcase its potential.

First, as always, let's think about the reduction function. Well, it'll be extremely basic — just compute the length of the current word, add it to the aggregate, and return the result.

Here's the reduction function:

function add_length($total_length, $word) {
   return $total_length + strlen($word);
}

Now, let's get to the invocation of array_reduce(). Since we want to begin with a total length of 0, so that'll be the value of the third argument to array_reduce().

Here's the complete code:

<?php

function add_length($total_length, $word) {
   return $total_length + strlen($word);
}

$words = ['as', 'hello', 'for'];

$total_length = array_reduce($words, 'add_length', 0);
echo $total_length;
10

So what do you say? Wasn't this easy?

Notice that in the callback provided to array_reduce(), there is absolutely no way to obtain the key corresponding to the element's value passed into the callback — the callback receives exactly two arguments: the arggregate value and the value of current element of the array.

Henceforth, if our reduction logic relies on the key of each element of the underyling array, we can NOT use array_reduce().

Filling with given values

A really handy function to use when we want to fill an array to a given length with a given value is array_fill().

Shown below is its syntax:

array_fill($start, $count, $value)

The first $start argument specifies the starting index; $count specifies the number of fills to perform; and $value specifies the fill value.

$count must be an integer in the range 0 - 2147483647, otherwise an exception would be raised.

Let's say we want to initialize an array with 10 elements, all set to 0. Since there is no native way to preset the length of an array in PHP when creating it, we ought to use array_fill() to accomplish this.

Using array_fill(), here's how we'd perform this initialization:

<?php

$arr = array_fill(0, 10, 0);
print_r($arr);

Because we need to begin at the very first index, the first argument is 0. Next, as 10 elements are desired in the created array, the second argument is 10. Lastly, as the desired initial value is 0, the third argument is 0.

Let's see the resulting array:

Array ( [0] => 0 [1] => 0 [2] => 0 [3] => 0 [4] => 0 [5] => 0 [6] => 0 [7] => 0 [8] => 0 [9] => 0 )

Exactly what we wanted.

Joining elements together

Recall the explode() string function that we saw in the PHP Strings — Functions chapter. It's used to split apart a string into individual chunks, where each chunk becomes an element of an array.

The complementary function to explode() is implode().

implode() works on arrays and serves to join all the elements together into a string.

In the official documentation of PHP, implode() is grouped under string functions, not array functions. However, we explore it along with arrays since often joining elements of an array into a string is an array-related utility in programming languages.

The function has two variants; one with two arguments, as follows:

implode($separator, $array)

and one with just one argument,

implode($array)

where the separator defaults to an empty string ('').

Let's see an example.

In the code below, we have an array of programming languages that we join together into a single string, with the substring ', ' delimiting them:

<?php

$words = ['Ada', 'Python', 'PHP', 'Java'];

echo implode(', ', $words);
Ada, Python, PHP, Java

With this same array, let's try the single-arg variant of implode():

<?php

$words = ['Ada', 'Python', 'PHP', 'Java'];

echo implode($words);
AdaPythonPHPJava

Since the separator in this variant is an empty string (''), we have all the programming languages joined tightly together to one another, without anything in between them.

Exploring more functions

Frankly speaking, the list of array functions in PHP is near exhaustive, with each function having numerous aspects to cover and requiring a decent amount of discussion.

Needless to say, it would be completely impractical to showcase all of the functions in this chapter. We've only discussed the ones here that we believe are frequently used and common across other programming languages as well.

At the same time, the interested reader is encouraged to check out the official documentation of PHP on array functions to explore the enormouse world of PHP array functions, including the following:

  • Cursor-related functions that are based on the concept of a 'cursor' pointing to an element of an array. In this category, we have current(), prev(), next(), reset(), end(), and key().
  • Diffing functions that compute the difference between two given arrays. In this category, we have array_diff(), array_diff_key(), array_diff_assoc(), and so on.
  • Intersection functions that compute the intersection of two given arrays. Here we have the functions array_intersect(), array_intersect_key(), array_intersect_assoc(), and so on.
  • Randomization functions that perform some random routine on a given array. shuffle() and array_rand() are the two functions to explore here.