How to Flatten an array in PHP (four methods)
There’s no built-in operate in PHP to flatten a multi-dimensional array, however it’s not a tough factor to do in PHP. In reality, it’s fairly straightforward.
We normally flatten arrays of information fetched from a database or an API. In real-world eventualities, we’d normally wish to take a number of fields off every row for displaying in our views.
Easy methods to flatten an array in PHP
On this tutorial, we’ll discover 4 methods of flattening arrays (two-dimensional and multi-dimensional) in PHP:
- Flatten two-dimensional arrays in PHP (when keys don’t matter)
- Pluck a listing of the given key/worth pairs from a PHP array
- Flatten a PHP array recursively I
- Flatten a PHP array recursively II
Flatten two-dimensional arrays in PHP
If in case you have a two-dimensional array, you’ll be able to flatten it by unpacking the array and passing it as an argument to the array_merge() operate.
// Every array has two Apple units in every class (iPads, telephones, and laptops) $merchandise = [ ['iPad Air', 'iPad pro'], ['iPhone 13', 'iPhone 13 mini'], ['MacBook Air', 'MacBook Pro'] ]; // Flatten the array $end result = array_merge(. $merchandise); print_r($end result);
And this would be the output:
Array ( [0] => iPad Air [1] => iPad professional [2] => iPhone 13 [3] => iPhone 13 mini [4] => MacBook Air [5] => MacBook Professional )
In PHP variations earlier than 8.1, if the $merchandise array has string keys, you could extract the values with array_values() first:
// . $end result = array_merge(. array_values($merchandise));
For PHP variations earlier than 7.4: if the $merchandise array is empty, the array_merge() can be invoked with out arguments. This may elevate an error. To keep away from the error, add an empty array [] to the array_merge() arguments:
// . $outcomes = array_merge([], . $merchandise);
Argument unpacking has been accessible since PHP 5.6+.
Be aware: Since PHP 8.1, unpacking the outer array with string keys (associative arrays) is feasible with out utilizing array_values() .
Pluck a listing of the given key/worth pairs from the array
If in case you have an array of arrays (two-dimensional), and also you wish to take a particular key (e.g., identify ) off every array and create an array of names, you need to use array_column() .
Think about you have fetched a listing of consumers from the database, and you’ve got the outcomes as a two-dimensional array. Now you wish to create an array containing the identify of every particular person.
Here is the way it’s achieved:
// Array representing a potential report set returned from a database $data = array( array( 'id' => 2135, 'first_name' => 'John', 'last_name' => 'Doe', ), array( 'id' => 3245, 'first_name' => 'Sally', 'last_name' => 'Smith', ), array( 'id' => 5342, 'first_name' => 'Jane', 'last_name' => 'Jones', ), array( 'id' => 5623, 'first_name' => 'Peter', 'last_name' => 'Doe', ) ); $first_names = array_column($data, 'first_name'); print_r($first_names);
Array ( [0] => John [1] => Sally [2] => Jane [3] => Peter )
Flattening arrays in PHP
To sum things up; if you want to flatten a two-dimensional array with numeric keys:
array_merge(. $twoDimensionalArray);
If you want to flatten a two-dimensional associative array:
array_merge(. array_values($twoDimensionalArray));
If you want a general solution to flatten an arbitrarily nested array and you don’t care about the keys:
function flatten_array(array $array): array $recursiveArrayIterator = new RecursiveArrayIterator( $array, RecursiveArrayIterator::CHILD_ARRAYS_ONLY ); $iterator = new RecursiveIteratorIterator($recursiveArrayIterator); return iterator_to_array($iterator, false); >
If you want a general solution to flatten an arbitrarily nested array and you do care about the keys:
function flatten_array_preserve_keys(array $array): array $recursiveArrayIterator = new RecursiveArrayIterator( $array, RecursiveArrayIterator::CHILD_ARRAYS_ONLY ); $iterator = new RecursiveIteratorIterator($recursiveArrayIterator); return iterator_to_array($iterator); >
As a side note, if you are only interested in all values with a specific key 1 :
$array = [ ['id' => 123, 'name' => 'aaa', 'class' => 'x'], ['id' => 124, 'name' => 'bbb', 'class' => 'x'], ['id' => 345, 'name' => 'ccc', 'class' => 'y'], ]; array_column($array, 'id'); // [123, 124, 345]
Flattening a two-dimensional array
array_merge(. $twoDimensionalArray);
array_merge takes a variable list of arrays as arguments and merges them all into one array. By using the splat operator ( . ), every element of the two-dimensional array gets passed as an argument to array_merge .
This works fine for merging associative arrays as well, but beware that the outer array is only allowed to have numeric keys:
$twoDimensionalArray = [ 'x' => ['first', 'array'], 'y' => ['second', 'array'] ]; $flattenedArray = array_merge(. $twoDimensionalArray); // Fatal error: Uncaught ArgumentCountError: array_merge() does not accept unknown named parameters
The solution is to use array_values in those cases:
$twoDimensionalArray = [ 'x' => ['first', 'array'], 'y' => ['second', 'array'] ]; $flattenedArray = array_merge(. array_values($twoDimensionalArray));
On PHP version 7.3 or lower, you will see the following if the input array is empty:
$twoDimensionalArray = []; array_merge(. $twoDimensionalArray); // Warning: array_merge() expects at least 1 parameter, 0 given.
You can solve this by passing a single empty array as an extra argument:
array_merge([], . $twoDimensionalArray);
A general solution for arbitrarily nested arrays
function flatten_array(array $array): array $recursiveArrayIterator = new RecursiveArrayIterator( $array, RecursiveArrayIterator::CHILD_ARRAYS_ONLY ); $iterator = new RecursiveIteratorIterator($recursiveArrayIterator); return iterator_to_array($iterator, false); >
For arbitrarily nested arrays we make use of the built-in iterators RecursiveArrayIterator and RecursiveIteratorIterator . It is important to note that we have to pass the flag CHILD_ARRAYS_ONLY to the ArrayIterator , otherwise it would iterate over public properties of objects as well, which you probably never want:
class Person public function __construct(public $name) <> > $array = [ new Person('Jake'), new Person('Charles') ]; flatten_array($array); // Without CHILD_ARRAYS_ONLY: // // [ // 0 => 'Jake', // 1 => 'Charles' // ] // // With CHILD_ARRAYS_ONLY: // // [ // 0 => Person Object, // 1 => Person Object // ]
Lastly, you can play around with the second argument of iterator_to_array , which indicates whether or not keys should be preserved. If you pass false , keys will not be preserved and the result will be a simple list. If you pass true (which is the default), keys will be preserved, meaning duplicate entries will be lost. Both approaches have their uses.
$employees = [ ['name' => 'Jake Peralta'], ['name' => 'Charles Boyle'] ]; flatten_array($employees); // [ // 0 => 'Jake Peralta', // 1 => 'Charles Boyle, // ] flatten_array_preserve_keys($employees); // [ // 'name' => 'Charles Boyle' // ]
Extracting values with a specific key
array_column is especially useful to extract all values with a given key from an array:
$array = [ ['id' => 123, 'name' => 'aaa', 'class' => 'x'], ['id' => 124, 'name' => 'bbb', 'class' => 'x'], ['id' => 345, 'name' => 'ccc', 'class' => 'y'], ]; array_column($array, 'id'); // [123, 124, 345]
The function accepts an optional third parameter that specifies which column to use as the index:
array_column($array, 'name', 'id'); // [123 => 'aaa', 124 => 'bbb', 345 => 'ccc']
It handles objects as well, as long as the properties are public:
class Person public function __construct(public int $id, public string $name) <> > $objects = [ new Person(12, 'John'), new Person(34, 'Jane') ]; array_column($objects, 'name', 'id'); // [12 => 'John', 34 => 'Jane']
While not useful in the context of flattening arrays, there’s another neat trick you can do with array_column : by passing null as the second argument, the array will be reindexed based on the third parameter:
$array = [ ['id' => 123, 'name' => 'aaa', 'class' => 'x'], ['id' => 124, 'name' => 'bbb', 'class' => 'x'], ['id' => 345, 'name' => 'ccc', 'class' => 'y'], ]; array_column($array, null, 'id'); // [ // 123 => ['id' => 123, 'name' => 'aaa', 'class' => 'x'], // 124 => ['id' => 124, 'name' => 'bbb', 'class' => 'x'], // 345 => ['id' => 345, 'name' => 'ccc', 'class' => 'y'], // ]