You are probably using array every day as a PHP developer, because it is the default collection type of data structure in PHP. What you might not be aware is that PHP provides tons of built-in array manipulation functions, they are more efficient compared to user land solution, because they are built into the core and designed to handle most of edge cases.
In this series of tutorials, we will be going through some built-in array functions. Show their possible use cases as comprehensively as we can. Hopefully this series will improve the way you deal with PHP array and make your code better.
Throughout the whole series, we will be operating on an array called $books:
$books = [
'Head First Design Patterns',
'Design Patterns: Elements of Reusable Object-Oriented Software',
'Agile Software Development, Principles, Patterns, and Practices',
'Patterns of Enterprise Application Architecture',
];
When we need a new format of an existing array, we can re-format it with a loop.
For example, to create a new format of $books as shown below:
[
[
'name' => 'Head First Design Patterns',
],
[
'name' => 'Design Patterns: Elements of Reusable Object-Oriented Software',
],
[
'name' => 'Agile Software Development, Principles, Patterns, and Practices',
],
[
'name' => 'Patterns of Enterprise Application Architecture',
],
]
We can do it manually:
$booksNew = [];
foreach ($books as $book) {
$booksNew[] = [
'name' => $book
];
}
A built-in PHP array function array_map allows us to apply a callback to each element of a array.
To accomplish the same task above, we can do:
$booksNew = array_map(function ($item) {
return ['name' => $item];
}, $books);
PHP provides another array function array_walk, which works similar to array_map.
To accomplish the same task above with array_walk, we can do:
array_walk($books, function (&$value, $key) {
return $value = ['name' => $value];
});
A few key differences we can see between array_map and array_walk:
Function array_map does not provide any way to pass array KEYs to the callback function. However it does allow us to pass in multiple parameters.
A nice trick to allow us pass both values and keys to the callback function.
array_map(function ($value, $key) {
}, $array, array_keys($array));
When we want to traverse an array, perform some logic and return a single value at the end. We will normally do it through a loop statement.
For example, to count total number of characters in $books array. We can do with a loop as shown below:
$totalChars = 0;
foreach ($books as $book) {
$totalChars += strlen($book);
}
PHP comes with a built-in array function array_reduce. It allows us to iteratively reduce the array to a single value using a callback function.
To accomplish the same task above, we can do:
$total = array_reduce($books, function ($totalChars, $current) {
return $totalChars += strlen($current);
}, 0)
The signature of array_reduce is worth mentioning here.
array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] )
The first parameter $array is where we supply the input array.
The second parameter $callback provides following function signature:
callback ( mixed $carry , mixed $item )
$carry carries the value of previous iteration.
$item holds the current value.
The third optional parameter, which has a default value of NULL, allows us to set the beginning value. In our case, we set it to 0, because the initial value of total characters should be zero.
When we need to extract the last value of an array, we will do typically:
$lastBook = $books[count($books) - 1];
One thing we need to take note here:
We could end up with something similar as shown below:
$lastBook = null;
if (isset($books[count($books) - 1])) {
$lastBook = $books[count($books) - 1];
}
A built-in PHP array function for such use case is array_pop. To extract the last value of $books, we can simply do:
$lastBook = array_pop($books);
Besides its performance improvement is that, this function handles empty array edge case itself. When the array is empty, it returns a predictable NULL value.
One caveat when using this function. The parameter is passed by reference to this function. It will change the supplied array besides returning the last value.
This side-effect can be demonstrated as shown below:
print_r($books);
$lastBook = array_pop($books);
print_r($books);
Result of running above script:
Array
(
``[0] => Head First Design Patterns
``[1] => Design Patterns: Elements of Reusable Object-Oriented Software
``[2] => Agile Software Development, Principles, Patterns, ``and` `Practices
``[3] => Patterns of Enterprise Application Architecture
)
Array
(
``[0] => Head First Design Patterns
``[1] => Design Patterns: Elements of Reusable Object-Oriented Software
``[2] => Agile Software Development, Principles, Patterns, ``and` `Practices
)
When we need to extract the first value of an array, we will do typically:
$firstBook = $books[0];
One thing we need to take note here:
We could end up with something similar as shown below:
$firstBook = null;
if (count($books) > 0) {
$firstBook = $books[0];
}
A built-in PHP array function for such use case is array_shift. To extract the first value of $books, we can simply do:
$firstBook = array_shift($books);
Besides its performance improvement is that, this function handles empty array edge case itself. When the array is empty, it returns a predictable NULL value.
One caveat when using this function. The parameter is passed by reference to this function like array_pop function. It will change the supplied array besides returning the last value.
This side-effect can be demonstrated as shown below:
print_r($books);
$lastBook = array_pop($books);
print_r($books);
Result of running above script:
Array
(
[0] => Head First Design Patterns
[1] => Design Patterns: Elements of Reusable Object-Oriented Software
[2] => Agile Software Development, Principles, Patterns, and Practices
[3] => Patterns of Enterprise Application Architecture
)
Array
(
[0] => Design Patterns: Elements of Reusable Object-Oriented Software
[1] => Agile Software Development, Principles, Patterns, and Practices
[2] => Patterns of Enterprise Application Architecture
)
When we need to add multiple elements to an existing array, we will do typically:clear
$books[] = 'Clean Code: A Handbook of Agile Software Craftsmanship';
$books[] = 'Refactoring: Improving the Design of Existing Code';
A built-in PHP array function array_push can make this more elegant. To add multiple elements to the end of $books, we can simply do:
array_push(
$books,
'Clean Code: A Handbook of Agile Software Craftsmanship',
'Refactoring: Improving the Design of Existing Code'
);
We need to be very clear about this function's parameters and return value. It can cause confusion if you aren't very clear about them.
To show the above points using code sample:
print_r($books);
$newNumOfElements = array_push(
$books,
'Clean Code: A Handbook of Agile Software Craftsmanship',
'Refactoring: Improving the Design of Existing Code'
);
print_r($books);
print_r($newNumOfElements);
The result of running above script:
Array
(
[0] => Head First Design Patterns
[1] => Design Patterns: Elements of Reusable Object-Oriented Software
[2] => Agile Software Development, Principles, Patterns, and Practices
[3] => Patterns of Enterprise Application Architecture
)
Array
(
[0] => Head First Design Patterns
[1] => Design Patterns: Elements of Reusable Object-Oriented Software
[2] => Agile Software Development, Principles, Patterns, and Practices
[3] => Patterns of Enterprise Application Architecture
[4] => Clean Code: A Handbook of Agile Software Craftsmanship
[5] => Refactoring: Improving the Design of Existing Code
)
6
When we need to prepend one or more elements to an existing array, we will do typically with a loop:
$bookToPrepend = 'Clean Code: A Handbook of Agile Software Craftsmanship';
for ($i = count($books); $i > 0; $i--) {
$books[$i] = $books[$i - 1];
}
$books[0] = $bookToPrepend;
A built-in PHP array function array_unshift provides an easy to use solution. To add prepend elements $books, we can simply do:
array_unshift(
$books,
'Clean Code: A Handbook of Agile Software Craftsmanship',
'Refactoring: Improving the Design of Existing Code'
)
Like array_push, we need to be very clear about this function's parameters and return value.
To show the above points using code sample:
print_r($books);
$newNumOfElements = array_unshift(
$books,
'Clean Code: A Handbook of Agile Software Craftsmanship',
'Refactoring: Improving the Design of Existing Code'
);
print_r($books);
print_r($newNumOfElements);
The result of running above script:
Array
(
[0] => Head First Design Patterns
[1] => Design Patterns: Elements of Reusable Object-Oriented Software
[2] => Agile Software Development, Principles, Patterns, and Practices
[3] => Patterns of Enterprise Application Architecture
)
Array
(
[0] => Clean Code: A Handbook of Agile Software Craftsmanship
[1] => Refactoring: Improving the Design of Existing Code
[2] => Head First Design Patterns
[3] => Design Patterns: Elements of Reusable Object-Oriented Software
[4] => Agile Software Development, Principles, Patterns, and Practices
[5] => Patterns of Enterprise Application Architecture
)
6
When we need to extract one part of an existing array, and assign its values to another new array. We will do typically:
$extractStartIndex = 1;
$extractLength = 2;
$extractedBooks = [];
for ($i = $extractStartIndex; $i < ($extractStartIndex + $extractLength); $i++) {
$extractedBooks[] = $books[$i];
}
A built-in PHP array function array_slice provides an easy to use solution. To extract one part of $books, we can simply do:
$extractedBooks = array_slice($books, 1, 2);
When we need to merge two arrays into one. We can do it manually with loops:
$otherBooks = [
'Clean Code: A Handbook of Agile Software Craftsmanship',
'Refactoring: Improving the Design of Existing Code'
];
foreach($otherBooks as $otherBook) {
$books[] = $otherBook;
}
A built-in PHP array function array_merge provides an elegant way. To merge $otherBooks with $books, we can simply do:
$books = array_merge($books, $otherBooks);
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. However if arrays contain numeric keys, the later values will be append to the first array.
We can demonstrate this point as shown below:
$firstArray = [1, 2, 3, 4];
$secondArray = [5, 6, 7, 8];
$resultArray = array_merge($firstArray, $secondArray);
print_r($resultArray);
$firstArray = ['first_name' => 'Eric'];
$secondArray = ['first_name' => 'David'];
$resultArray = array_merge($firstArray, $secondArray);
print_r($resultArray);
The result of running above script:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
[6] => 7
[7] => 8
)
Array
(
[first_name] => David
)
Function array_merge is used often to provide some default settings, yet still allow user to overwrite them.
For example:
public function config ($config = []) {
$this->settings = array_merge($this->default, $config);
...
}
When we need to get the sum of an array of numeric values. We can do it manually with loop:
$numbers = [1, 2, 3, 4, 5];
$sum = 0;
foreach($numbers as $number) {
$sum += $number;
}
A built-in PHP array function array_sum provides a solution out of box. To sum up values of $numbers, we can simply do:
$sum = array_sum($numbers);
What happens if the supplied array parameter does not contain numeric values?
array_sum will simply return 0 as shown below:
print_r(array_sum($books));
The result of running above script: 0
When we need to filter elements of an array, we will normally handle with loop statements.
For example, to remove all books contain string "Design" from $books array, we can do:
for ($i = 0; $i < count($books); $i++) {
if (false !== strpos($books[$i], 'Design')) {
unset($books[$i]);
}
}
A built-in PHP array function array_filter provides a solution with an elegant syntax.
To accomplish the same task with array_filter, we can do:
$books = array_filter($books, function($book) {
return (false === strpos($book, 'Design'));
});
Function array_filter accepts a closure as its second parameter and returns a new array. This is sometimes referred to as functional programming.
Functional programming is a powerful programming paradigm. And it makes our code easy to understand when used properly.