Five Smart Ways to Use Collapse
Smart Ways to use the Collapse Method in Laravel Collections: 5 Practical Examples
April 14, 2023
1k ViewsLaravel offers an array of features that make development faster, more efficient, and more enjoyable. One of these features is the Laravel Collection, a powerful and flexible set of tools to work with arrays and objects. In this article, we will delve into the collapse()
method and explore five smart ways to use it for a Laravel Collection.
How does collapse()
work?
Under the hood, the collapse()
method calls a static method on the Arr
class and the result is returned. The Collect
class represents a Laravel Collection, and the Arr
class contains the static method collapse()
that is responsible for collapsing an array of arrays into a single array.
Consider this implementation:
class Collect
{
/**
* The items contained in the collection.
* @var array<TKey, TValue>
*/
protected $items = [];
/**
* Collapse the collection of items into a single array.
* @return static<int, mixed>
*/
public function collapse()
{
return new static(Arr::collapse($this->items));
}
}
class Arr
{
/**
* Collapse an array of arrays into a single array.
* @param iterable $array
* @return array
*/
public static function collapse($array)
{
$results = [];
foreach ($array as $values) {
if ($values instanceof Collection) {
$values = $values->all();
} elseif (! is_array($values)) {
continue;
}
$results[] = $values;
}
return array_merge([], ...$results);
}
}
Let's break down the steps of the collapse()
method:
- In the Collect class, the
collapse()
method is called on a collection instance. This method then delegates the collapsing process to theArr::collapse()
method by passing$this->items
as the parameter, which represents the items contained in the collection.
public function collapse()
{
return new static(Arr::collapse($this->items));
}
- The
Arr::collapse()
method takes an iterable (in this case, an array) as its parameter.
public static function collapse($array)
{
// ...
}
- An empty
$results
array is initialized. This array will store the collapsed values.
$results = [];
- The method iterates through the input
$array
using a foreach loop. For each element$values
in the$array
:
- If
$values
is an instance of the Collection class, it calls theall()
method on$values
to retrieve the underlying array. - If
$values
is not an array, the loop continues to the next iteration, effectively skipping the current element. - If
$values
is an array, it is added to the$results
array.
foreach ($array as $values) {
if ($values instanceof Collection) {
$values = $values->all();
} elseif (! is_array($values)) {
continue;
}
$results[] = $values;
}
- Finally, the
array_merge()
function is used to merge the arrays stored in the$results
array. The spread operator...
is used to pass the arrays as separate arguments toarray_merge()
.
return array_merge([], ...$results);
The resulting array is returned, which represents the collapsed version of the original array of arrays.
1. Combining Nested Arrays
One common use case for the collapse()
method is to combine nested arrays in a Laravel Collection. When working with complex data structures, you might often encounter multi-dimensional arrays. The collapse()
method allows you to flatten these nested arrays into a single-level array, making it easier to manipulate and display the data.
$nestedArray = collect([
['apple', 'banana'],
['carrot', 'broccoli'],
]);
$collapsed = $nestedArray->collapse();
// Output: ['apple', 'banana', 'carrot', 'broccoli']
In the example, we will break down the steps the collapse()
method takes to flatten the nested array.
-
Create a nested array: The first step is defining a nested array called
$nestedArray
. In this case, it is a two-dimensional array containing two inner arrays. -
Convert the nested array into a collection: Next, the
collect()
function is used to convert the nested array into a Laravel Collection object. This allows you to take advantage of the Collection's powerful methods, such ascollapse()
. -
Apply the collapse() method: Now that
$nestedArray
is a Laravel Collection object, you can use thecollapse()
method on it. Thecollapse()
method iterates through each inner array within the collection and merges the items into a new single-level collection. -
Final result: After the
collapse()
method finishes processing, you are left with a single-level collection containing all the items from the original nested array.
2. Merging Related Data Sets
In some scenarios, you may have data sets that are related but stored separately. The collapse()
method can help you merge these data sets effortlessly. For example, consider you have a list of products and their respective images stored in separate arrays. By using the collapse()
method, you can combine them into a single collection.
$products = collect([
['id' => 1, 'name' => 'Laptop'],
['id' => 2, 'name' => 'Smartphone'],
]);
$images = collect([
['product_id' => 1, 'url' => 'laptop.jpg'],
['product_id' => 2, 'url' => 'smartphone.jpg'],
]);
$combined = collect([$products, $images])->collapse();
// result
// [
// ['id' => 1, 'name' => 'Laptop'],
// ['id' => 2, 'name' => 'Smartphone'],
// ['product_id' => 1, 'url' => 'laptop.jpg'],
// ['product_id' => 2, 'url' => 'smartphone.jpg'],
// ]
Let's break down the example provided step by step:
-
Create two collections with related data: Here, we create two separate collections: one for the products and another for the images. Each collection consists of an array of associative arrays containing the relevant data.
-
Create a new collection with the two previous collections: In this step, we create a new collection called $combined and pass an array containing the
$products
and$images
collections as its argument. This results in a nested collection.
$combined = collect([$products, $images]);
-
Use the
collapse()
method to flatten the nested collection: Finally, we call thecollapse()
method on the$combined
collection. This method iterates over each item in the outer collection and merges the inner collections into a single-level collection.
The collapse()
method has taken the nested collection and flattened it into a single-level collection, merging the $products
and $images
collections together. Now, you have a unified collection with both product and image data that can be easily manipulated or displayed.
3. Simplifying Hierarchical Data
The collapse()
method can also be used to simplify hierarchical data structures. If you have a multi-level category system, you might want to display all categories in a single list. The collapse()
method can help you achieve this by flattening the hierarchy.
$categories = collect([
['id' => 1, 'name' => 'Electronics', 'subcategories' => [
['id' => 2, 'name' => 'Computers'],
['id' => 3, 'name' => 'Smartphones'],
]],
['id' => 4, 'name' => 'Home Appliances', 'subcategories' => [
['id' => 5, 'name' => 'Washing Machines'],
['id' => 6, 'name' => 'Refrigerators'],
]],
]);
$flattened = $categories->pluck('subcategories')->collapse();
// Output: [
// ['id' => 2, 'name' => 'Computers'],
// ['id' => 3, 'name' => 'Smartphones'],
// ['id' => 5, 'name' => 'Washing Machines'],
// ['id' => 6, 'name' => 'Refrigerators'],
// ]
Let's break down the process step by step:
-
First, we create a Laravel Collection
$categories
containing an array of category arrays, each with an id, name, and a nested subcategories array. -
Next, we use the
pluck()
method on the$categories
collection to retrieve the subcategories arrays from each category. The result is a new collection containing only the subcategories arrays.
$subcategoriesCollection = $categories->pluck('subcategories');
// Output: [
// [
// ['id' => 2, 'name' => 'Computers'],
// ['id' => 3, 'name' => 'Smartphones'],
// ],
// [
// ['id' => 5, 'name' => 'Washing Machines'],
// ['id' => 6, 'name' => 'Refrigerators'],
// ],
// ]
- Finally, we apply the
collapse()
method on the$subcategoriesCollection
to flatten the nested arrays into a single-level array. Thecollapse()
method iterates through each array within the collection and merges the elements together into a new collection.
$flattened = $subcategoriesCollection->collapse();
// Output: [
// ['id' => 2, 'name' => 'Computers'],
// ['id' => 3, 'name' => 'Smartphones'],
// ['id' => 5, 'name' => 'Washing Machines'],
// ['id' => 6, 'name' => 'Refrigerators'],
// ]
We used the pluck()
method to extract the subcategories arrays from each category, and then applied the collapse()
method to flatten the nested arrays into a single-level array. The final result is a new Laravel Collection containing all subcategories in a flattened structure.
4. Combining Query Results
When working with multiple database tables, you might need to combine results from different queries. The collapse()
method can help you achieve this by merging the results into a single collection.
$users = DB::table('users')->select('id', 'name')->get();
$orders = DB::table('orders')->select('id', 'user_id')->get();
$combinedResults = collect([$users, $orders])->collapse();
Here's a step-by-step explanation of how the collapse method works in the example:
-
Retrieve users data:
This line queries the 'users' database table, selecting the
'id'
and'name'
columns for all records. Theget()
method retrieves the results and returns them as a Collection.
$users = DB::table('users')->select('id', 'name')->get();
-
Retrieve orders data: This line queries the
'orders'
database table, selecting the'id'
and'user_id'
columns for all records. Similar to the previous step, theget()
method retrieves the results and returns them as a Collection.
$orders = DB::table('orders')->select('id', 'user_id')->get();
-
Create a nested Collection: Here, we create a new Laravel Collection containing two elements: the
$users
Collection and the$orders
Collection. This results in a nested Collection with two levels.
collect([$users, $orders])
-
Collapse the nested Collection: The
collapse()
method is called on the nested Collection created in step 3. It iterates over the first level of the Collection and merges all the elements (the$users
and$orders
Collections) into a single-level Collection.
->collapse();
-
Store the combined results: The collapsed Collection, which contains both the users and orders data in a single-level Collection, is stored in the
$combinedResults
variable.
$combinedResults = ...
The collapse()
method in this example is used to combine the results of two separate database queries (users and orders) into a single-level Laravel Collection.
5. Unifying Validation Errors
If you're using Laravel's built-in validation, you might receive errors as a multi-dimensional array. To display these errors in a unified manner, you can use the collapse()
method to flatten the array into a single collection.
$errors = collect([
'name' => ['The name field is required.'],
'email' => ['The email field is required.', 'The email must be a valid email address.'],
]);
$flattenedErrors = $errors->collapse();
// Output:
// [
// 'The name field is required.',
// 'The email field is required.',
// 'The email must be a valid email address.',
// ]
Let's walk through the process step by step.
-
Creating the initial Collection: First, a new Laravel Collection is created using the
collect()
function. The input is an associative array containing two key-value pairs:'name'
and'email'
. Each key is associated with an array containing one or more error messages. -
Applying the collapse() method: Next, the
collapse()
method is called on the$errors
collection. The method iterates through the input collection and merges the nested arrays into a single-level collection. In this case, it combines the arrays associated with the keys'name'
and'email'
.
$flattenedErrors = $errors->collapse();
- Resulting Collection: After the
collapse()
method is applied,$flattenedErrors
contains a new collection that has a single-level structure with all error messages:
[
'The name field is required.',
'The email field is required.',
'The email must be a valid email address.',
]
The collapse()
method takes a multi-dimensional collection and flattens it into a single-level collection. This simplifies the data structure, making it easier to process or display the information. In the given example, the collapse()
method transformed a nested collection of validation error messages into a single-level collection containing all error messages.
Wrapping up
We explored five ingenious ways to use the collapse()
method for a Laravel Collection. These examples demonstrate the versatility and power of the collapse()
method, enabling you to simplify and manipulate data effectively. Whether you're working with nested arrays, merging related data sets, or simplifying hierarchical data, the collapse()
method can be an invaluable tool in your Laravel development arsenal.