In Laravel, finding a specific value from a multi-dimensional array can be challenging. One way to overcome this issue is to use a recursive function to search for the desired value. This approach enables developers to search through nested arrays, objects, and collections to retrieve specific values or data.
The recursive search function provides a powerful and flexible way to locate values within complex data structures. By leveraging PHP's built-in recursion capability, Laravel developers can create custom functions that can scan through arrays or objects to find the required data quickly.
This approach is particularly useful for handling large datasets, such as those found in e-commerce or social media platforms, where developers need to search for specific values or data points. With a recursive search function in Laravel, developers can efficiently locate the required data, reducing the time and effort required to work with complex data structures.
Different methods to search array recursively in Laravel
In Laravel, there are several methods to search for an array recursively:
- Recursive function: A recursive function can be written that will loop through each array element until the desired result is found.
array_walk_recursive
: This PHP function can be used to loop through a multidimensional array recursively.array_filter
with a callback function: This function can be used to filter out array elements that don't meet a certain criteria, and a callback function can be used to search recursively.RecursiveIteratorIterator
: This PHP class can be used to loop through a multidimensional array recursively.- Collection macro: In Laravel, the
Collection
class can be extended with a macro to make it recursive. The macro will loop through each element of the collection, and if it finds an array or an object, it will convert it to a collection and apply the macro recursively.
Method-1: Using array_filter
An array that contains other arrays is called a multidimensional array. Here is an example.
$students = [
[
'id' => 1,
'name' => 'Mario',
'grade' => 78,
'games' => ['chess', 'cricket']
],
[
'id' => 2,
'name' => 'Adam',
'grade' => 81,
'games' => ['football', 'swimming', 'rugby']
],
[
'id' => 3,
'name' => 'Salma',
'grade' => 94,
'games' => ['athletics', 'checkers', 'football']
],
];
To search records from this multidimensional array, we can use the array_filter()
function in combination with a custom callback function. The callback function will receive each sub-array as an argument and should return true if the array matches the search criteria, or false otherwise.
For example, to search for all students who play football, you can use the following code:
$search = 'football';
$results = array_filter($students, function($student) use ($search) {
return in_array($search, $student['games']);
});
This code creates a new array $results that contains only the sub-arrays of $students that have 'football' in their 'games' array. The in_array() function checks whether the given $search value is present in the 'games' array of each $student sub-array.
For example, to filter an array of students to only include those with a grade of 80 or higher:
$passed_students = array_filter($students, function($student) {
return $student['grade'] >= 80;
});
$scores = array_map(function($student) {
return $student['name']. ' stored '. $student['grade']. '%';
}, $passed_students);
The resulting $passed_students
array contains only the students who passed with a grade of 80 or higher, and the $scores
array contains a list of strings that show each student's name and grade in the format "<name> scored <grade>%".
Method-2: Using array_walk_recursive
Here's an example of using array_walk_recursive
to search an array recursively in Laravel:
$students = [
[
'id' => 1,
'name' => 'Mario',
'grade' => 78,
'games' => ['chess', 'cricket']
],
[
'id' => 2,
'name' => 'Adam',
'grade' => 81,
'games' => ['football', 'swimming', 'rugby']
],
[
'id' => 3,
'name' => 'Salma',
'grade' => 94,
'games' => ['athletics', 'checkers', 'football']
],
];
$searchResults = [];
array_walk_recursive($students, function ($value, $key) use (&$searchResults) {
if ($key === 'name' && strpos($value, 'al') !== false) {
$searchResults[] = $value;
}
});
print_r($searchResults); // Output: Array ( [0] => Mario [1] => Salma )
In this example, array_walk_recursive
is used to iterate over each element in the $students
array recursively, and a callback function is called for each element. In this callback function, we check if the current element's key is "name" and if its value contains the substring "al". If both conditions are true, we add the value to the $searchResults
array.
Method-3: Using Laravel collection macro
A Laravel collection is a special array that enables you to run and chain many methods on it. Collections simplify data sorting and filtering.
$names = collect([
['Jane', 'Lorem', 'Hitesh'],
['Doe', 'Ipsum', 'Rajesh']
])->collapse()->all();
The helper functions like collect
, collapse
, all
originate from the Illuminate\Support\Collection
class. The collect
method wraps the given array to produce (immutable) Laravel collection.
You can then chain other methods like collapse
to create a single array from the subarrays and the all
method to return the new array.
As you can see from the example, Laravel collections simplify working with arrays. It relieves you from the stress of returning separate arrays before applying another PHP function, as we did with the $students
data.
$names = ['Jane', 'Lorem', 'Hitesh', 'Doe', 'Ipsum', 'Rajesh'];
$collection = collect($names)->map(function (string $name) {
return strtoupper($name);
})->sort()->values()->all();
Sometimes you want to add custom methods to a Laravel collection, especially if you lack a predefined method for a goal. For example, when doing a Laravel find array recursively. You can extend the extra functionality using a macro.
Here is an example.
Create a macro for recursive search
A nested array is treated as a normal array if it is passed into a Laravel collection. That is why writing (in app\Providers\AppServiceProvider.php
) a macro is the solution to finding an array recursively.
\Illuminate\Support\Collection::macro('recursive', function () {
return $this->map(function ($data) {
if (is_array($data)) {
return collect($data)->recursive();
}
if (is_object($data)) {
return collect($data)->recursive();
}
return $data;
});
});
We created a macro method called recursive
using the Collection
class' macro method. The recursive
macro closure accepts the Collection
class' other methods like map
via the $this
object. The map
function recursively creates a collection from the parsed array's children. The macro works by iterating through each element in the collection and recursively calling itself if the element is also an array or an object, until all nested elements have been traversed. If the element is not an array or an object, it is simply returned as is.
Let's use the macro to find the nested $students
array.
$collection = collect($students)->recursive();
Input
Output
Summary
Searching an array recursively is a common requirement in many programming tasks, including those performed in Laravel. There are several methods to achieve this in Laravel, including using the built-in array_walk_recursive
function, creating a custom macro for the Illuminate\Support\Collection
class, and using the array_filter
and array_map
functions in combination.
The array_walk_recursive
function allows us to apply a callback function to each element of an array recursively. This can be useful when we want to manipulate or filter the array elements based on some criteria.
In Laravel, we can create a custom macro for the Illuminate\Support\Collection
class to enable recursive searching of the array elements. This is achieved by mapping the array elements to a new collection and recursively calling the macro on nested arrays.
Another approach is to use the array_filter
and array_map
functions together to first filter the array elements based on some criteria and then map them to a new array.
You just learned Laravel find array recursively using macros. Are you interested in exploring the power of macros and collections? Here is a list of more methods you to use in your project.