Five Ways to Use the Combine Method
Leveraging the Power of Laravel Collections: 5 Neat Ways to Use the 'Combine' Method
April 18, 2023
2k ViewsLaravel collections are a powerful and flexible tool that provides a convenient and expressive way to work with arrays of data. One of the most useful methods available in Laravel collections is the combine method. It allows you to combine two separate collections into a single one by using the values of one collection as keys and the values of the other collection as the corresponding values. In this article, we will explore 5 different ways to use the combine method on a Laravel collection, complete with examples and explanations.
How does combine work?
Under the hood the combine method uses the native PHP function array_combine() which allows you to create a new collection by using the current collection as keys and another collection or array for its values. The Collection class combines two collections and returns a new Collection instance. Here is what that looks like:
/**
* @param \Illuminate\Contracts\Support\Arrayable<array-key, TCombineValue>|iterable<array-key, TCombineValue> $values
* @return static<TValue, TCombineValue>
*/
public function combine($values)
{
return new static(array_combine($this->all(), $this->getArrayableItems($values)));
}
Here's a step-by-step explanation of how the combine method works:
- The Collection class is instantiated with an optional array of items passed to the constructor. If no items are provided, an empty array is used as the default. The
getArrayableItemsmethod is called within the constructor to convert any non-array input (e.g., an instance of Arrayable, Enumerable, Traversable, Jsonable, or JsonSerializable) into an array format.
public function __construct($items = [])
{
$this->items = $this->getArrayableItems($items);
}
- The
combinemethod takes an input parameter$values, which can be an array or an instance of Arrayable, Enumerable, Traversable, Jsonable, or JsonSerializable.
public function combine($values)
{
return new static(array_combine($this->all(), $this->getArrayableItems($values)));
}
- The
allmethod is called on the current collection, which returns all of the items in the collection as an array. This array represents the keys of the resulting combined collection.
public function all()
{
return $this->items;
}
- The
getArrayableItemsmethod is called on the$valuesinput parameter, which converts the input into an array format. This array represents the values of the resulting combined collection.
protected function getArrayableItems($items)
{
//...
}
- The
array_combinefunction is called, which takes two arrays as input: the first array is used as the keys, and the second array is used as the corresponding values. This function returns a new associative array with the combined keys and values.
array_combine($this->all(), $this->getArrayableItems($values))
- Finally, a new instance of the
Collectionclass is created with the combined associative array, and this new collection is returned as the result of thecombinemethod.
The combine method works by taking two collections or arrays, using one as the keys and the other as the corresponding values, and creating a new combined collection with these keys and values. This process involves converting input values into an array format, using the array_combine function to merge the keys and values, and then creating a new instance of the Collection class with the merged data.
1. Creating an associative array from two separate collections
The most basic use case for the combine method is to create an associative array from two separate collections. This is useful when you have a set of keys in one collection and their corresponding values in another collection.
$keys = collect(['name', 'email', 'age']);
$values = collect(['John Doe', '[email protected]', 28]);
$combined = $keys->combine($values);
// Result: [
// 'name' => 'John Doe',
// 'email' => '[email protected]',
// 'age' => 28
// ]
In this example, the $keys collection contains the keys, and the $values collection contains their corresponding values. The combine method is then used to merge these two collections into a single associative array.
2. Combining keys and values from the same collection
Sometimes you may have a single collection containing both keys and values, and you need to extract them into an associative array. The combine method can help you achieve this.
$data = collect(['name', 'John Doe', 'email', '[email protected]', 'age', 28]);
$keys = $data->filter(fn ($value, $key) => $key % 2 === 0);
$values = $data->filter(fn ($value, $key) => $key % 2 !== 0);
$combined = $keys->combine($values);
// Result: [
// 'name' => 'John Doe',
// 'email' => '[email protected]',
// 'age' => 28
// ]
The code performs the following steps:
- Create a flat collection
$datacontaining keys and values in an alternating pattern.
$data = collect(['name', 'John Doe', 'email', '[email protected]', 'age', 28]);
- Filter the
$datacollection to create a new collection$keysthat contains only the even-indexed items, which represent the keys in the desired associative array. The filter function is using an arrow function that checks whether the index$keyis even by using the modulus operator ($key % 2 === 0).
$keys = $data->filter(fn ($value, $key) => $key % 2 === 0);
- Similarly, filter the
$datacollection to create another collection$valuesthat contains only the odd-indexed items, which represent the values in the desired associative array. The arrow function checks whether the index$keyis odd by using the modulus operator ($key % 2 !== 0).
$values = $data->filter(fn ($value, $key) => $key % 2 !== 0);
- Use the
combinemethod on the$keyscollection and pass the$valuescollection as a parameter. This creates a new associative array with keys from the$keyscollection and corresponding values from the$valuescollection. The result is assigned to the variable$combined.
$combined = $keys->combine($values);
- After executing this code, the
$combinedcollection will look like this:
[
'name' => 'John Doe',
'email' => '[email protected]',
'age' => 28
]
This shows how to create an associative array from a flat array by filtering out the keys and values separately and then combining them using the Laravel collection's combine method.
3. Generating a URL query string from two collections
The combine method can be used to create a URL query string by combining keys and values from two separate collections. This can be particularly useful when working with dynamic filters or search parameters.
Here is an example of how to do that:
$keys = collect(['search', 'filter', 'sort']);
$values = collect(['laptop', 'price', 'asc']);
$combined = $keys->combine($values)->map(function ($value, $key) {
return "{$key}={$value}";
})->implode('&');
// Result: 'search=laptop&filter=price&sort=asc'
The $keys collection contains the query parameter keys, and the $values collection contains their corresponding values. The combine method is used to merge these two collections into a single associative array. We then use the map method to concatenate the keys and values with an equal sign, followed by the implode method to join the resulting strings with an ampersand, creating a URL query string. Let's go through the code step by step:
-
The
$keysvariable is assigned a Collection created from an array containing three strings: 'search', 'filter', and 'sort'. -
The
$valuesvariable is assigned a Collection created from an array containing three strings: 'laptop', 'price', and 'asc'. -
The combine method is called on the
$keysCollection, which combines the$keysand$valuesCollections by using the values from$keysas keys and the values from$valuesas values. The resulting Collection would look like this:
[
'search' => 'laptop',
'filter' => 'price',
'sort' => 'asc'
]
- The
mapmethod is called on the combined Collection, which iterates over each key-value pair and applies the anonymous function to transform the value. The anonymous function takes$valueand$keyas arguments and returns a string with the format "key=value". The resulting Collection would look like this:
['search=laptop', 'filter=price','sort=asc']
- Finally, the
implodemethod is called on the mapped Collection, which joins the elements of the Collection into a single string, separated by the given delimiter '&'. The resulting string would look like this:
'search=laptop&filter=price&sort=asc'
This can be useful when you want to create a query string from two arrays of keys and values, which can be used as a URL query string or in an HTTP request.
4. Merging two collections with a custom delimiter
Sometimes you may have two collections containing related data, and you need to merge them with a custom delimiter. The combine method can help you achieve this.
$authors = collect(['John Doe', 'Jane Smith', 'Robert Brown']);
$books = collect(['The Adventure', 'The Mystery', 'The Discovery']);
$combined = $authors->combine($books)->map(function ($book, $author) {
return "{$author} - {$book}";
})->values();
// Result: ['John Doe - The Adventure', 'Jane Smith - The Mystery', 'Robert Brown - The Discovery']
Let's break down the code step by step:
-
The
collect()function is used to create two separate Laravel Collection instances. One for$authorsand another for $books. The$authorsCollection contains three author names, and the$booksCollection contains three book titles. -
Next, the
combine()method is called on the$authorsCollection, and the$booksCollection is passed as an argument. Thecombine()method creates a new Collection instance by combining the keys of the first Collection with the values of the second Collection. In this case, the author names in the$authorsCollection will be the keys, and the book titles in the$booksCollection will be the values:
$combined = $authors->combine($books)
[
'John Doe' => 'The Adventure',
'Jane Smith' => 'The Mystery',
'Robert Brown' => 'The Discovery'
]
- The
map()method is then called on the$combinedCollection. Themap()method iterates through the Collection and applies a callback function to each key-value pair. The callback function takes two arguments: the value (book title) and the key (author name). Inside the callback function, a formatted string is created by interpolating the author name and book title:
->map(function ($book, $author) {
return "{$author} - {$book}";
})
[
'John Doe' => 'John Doe - The Adventure',
'Jane Smith' => 'Jane Smith - The Mystery',
'Robert Brown' => 'Robert Brown - The Discovery'
]
- Finally, the
values()method is called on the$combinedCollection. Thevalues()method resets the keys of the Collection and returns a new Collection instance with numeric keys:
->values();
[
0 => 'John Doe - The Adventure',
1 => 'Jane Smith - The Mystery',
2 => 'Robert Brown - The Discovery'
]
This example creates a Collection of author names and a Collection of book titles, combines them into a new Collection, formats each author-title pair into a single string, and finally resets the keys to be numeric.
5. Combining collections with different data types
The combine method can be used to merge collections with different data types, such as strings, integers, and arrays.
$keys = collect(['name', 'age', 'hobbies']);
$values = collect(['John Doe', 30, ['reading', 'swimming', 'travelling']]);
$combined = $keys->combine($values);
// Result: [
// 'name' => 'John Doe',
// 'age' => 30,
// 'hobbies' => ['reading', 'swimming', 'travelling']
// ]
In this example, the $keys collection contains the keys, and the $values collection contains their corresponding values of different data types. The combine method is used to merge these two collections into a single associative array, preserving the original data types.
Wrapping Up
The combine method on a Laravel collection is a versatile tool that can be used in various scenarios to merge collections effectively. By understanding these use cases and examples, you can harness the power of Laravel collections to manipulate and transform your data efficiently. No matter the complexity of your data or the specific requirements of your application, the combine method offers an elegant and intuitive solution for merging collections.