If you use Laravel every day or have used it in the past, you may have already noticed how Collections
are an important if not fundamental part of the framework.
Some sites and even the official documentation often call Collections: “Arrays with steroids” and in this article you will know why.
An Array is a simple data structure that contains one or more elements in a single variable. Arrays in PHP however have one major problem, they are not Object Oriented.
Collections
on the other hand is a powerful Object Oriented feature that expands the possibilities when working with arrays in Laravel. Besides, Collections
allows us to write code more efficiently in an easier way.
The helper method collect()
returns a new instance of the Illuminate\Support\Collection
class. Therefore, creating a collection is as simple as:
$collection = collect([1, 2, 3]);
$collection = collect(['product' => 'Table', 'price' => 200]);
where()
The where()
method filters a Collection
by a given key/value pair. This method can receive up to three parameters, the first being the key you want to search, the second is the operator (=, <>, >=) and the third parameter is the value you want to compare.
Let’s say we have an online shop, and the user wants to filter the products by price, using this method will simplify this by a lot.
In the example below, we are filtering all products with price equal to $100.
$collection = collect([
['product' => 'Table', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Lamp', 'price' => 150],
['product' => 'Mattress', 'price' => 100],
]);
$filtered = $collection->where('price', 100);
$filtered->all();
/*
[
['product' => 'Chair', 'price' => 100],
['product' => 'Mattress', 'price' => 100],
]
*/
Remember that the second parameter of the function is the operator but if the third parameter is omitted, the default operator is =
so you can change the operator if you need to “greater or equal (>=
) $ 100″ for example.
This two snippets below return exactly the same result:
$collection = collect([
['product' => 'Table', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Lamp', 'price' => 150],
['product' => 'Mattress', 'price' => 100],
]);
$filtered = $collection->where('price', 100);
$filtered = $collection->where('price', '=', 100);
pluck()
The pluck()
method returns all values from a given key. Let me show you how extremely useful this can be.
Consider the same example above, now imagine you need an array containing just the name of all the products, how would you do it? Exactly, using pluck()
.
$collection = collect([
['product' => 'Table', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Lamp', 'price' => 150],
['product' => 'Mattress', 'price' => 100],
]);
$filtered = $collection->pluck('product');
$filtered->all();
/*
['Table', 'Chair', 'Lamp', 'Mattress']
*/
With this method you can also set what the key of the value in the response is, as in the example above we only have two properties in each item in the array, the key would have to be price
.
$collection = collect([
['product' => 'Table', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Lamp', 'price' => 150],
['product' => 'Mattress', 'price' => 100],
]);
$filtered = $collection->pluck('product', 'price');
$filtered->all();
/*
["200" => "Table", "100" => "Mattress", "150" => "Lamp"]
*/
Another important fact about this method that I need to mention is that if you have an object with nested properties, you can use the “dot” notation to access these values. I explain what I mean with the example below:
$collection = collect([
[
'speakers' => [
'first_day' => ['Rosa', 'Alberto'],
'second_day' => ['Angela', 'Monica'],
],
],
]);
$filtered = $collection->pluck('speakers.first_day');
$filtered->all();
/*
['Rosa', 'Alberto']
*/
I don’t know about you, but I find this method extremely useful for many situations.
contains()
The contains()
method determines if the collection contains a certain item. You can pass a function to the method, which will determine if there is an element in the collection that matches a certain condition. This is the most basic function of this method.
$collection = collect([1, 2, 3, 4, 5]);
$collection->contains(function ($value, $key) {
return $value > 5;
});
// false
Once again, let’s use our product collection as an example. Let’s think about the situation where we need to check if we have a certain product in our shop, we could use this method, which will return true or false, if the product exists in the shop or not.
$collection = collect([
['product' => 'Table', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Lamp', 'price' => 150],
['product' => 'Mattress', 'price' => 100],
]);
$filtered = $collection->contains('product', 'Chair');
// true
duplicates()
Another method that can be very useful is duplicates()
. It retrieves and returns duplicate values from the collection. In this first example, a very simple situation, but you can already understand how the method works.
The collection below contains 5 elements, 2 of which have repetitions (a, b), the method then returns a new array where the key refers to the position of the repeated element in the original array.
$collection = collect(['a', 'b', 'a', 'c', 'b']);
$collection->duplicates();
// [2 => 'a', 4 => 'b']
For example, we have two letters ‘a’ in the collection, so the method returns us [2 => 'a', 4 => 'b']
indicating that we have a repeat of the letter ‘a’ at position 2 in the original collection and repeat of the letter ‘b’ at position 4.
Now with a realistic example. Let’s say we registered some users, but the unique email validation wasn’t working perfectly and because of that we now have duplicate emails in our system and we need to find those duplicates, with the duplicates()
method this becomes a very simple task:
$users = collect([
['email' => 'rosa@example.com', 'profession' => 'Project manager'],
['email' => 'alberto@example.com', 'profession' => 'Developer'],
['email' => 'angela@example.com', 'profession' => 'Project analyst'],
['email' => 'alberto@example.com', 'profession' => 'Developer'],
['email' => 'monica@example.com', 'profession' => 'Graphic designer'],
['email' => 'alberto@example.com', 'profession' => 'Developer N2'],
]);
$users->duplicates('email');
// [3 => 'alberto@example.com', 5 => 'alberto@example.com']
firstWhere()
The firstWhere()
method returns the first element of the collection with the key/value pair that matches a given value. We’ve already seen the where()
method, and it looks like this method doesn’t do much more, but you’d need a loop, an if and maybe a break, just to be able to reproduce what this method does.
The example below, very similar to the where() method example, with one exception, instead of returning two values, it returns only one, the first occurrence of a product with a value equal to $100.
$collection = collect([
['product' => 'Table', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Lamp', 'price' => 150],
['product' => 'Mattress', 'price' => 100],
]);
$filtered = $collection->firstWhere('price', '100');
$filtered->all();
// ['product' => 'Chair', 'price' => 100]
And our last method of the list, the groupBy(), usually is an operation done directly using SQL in the database, but not always the data that we want to manipulate comes directly from there, in this case we can use this method to solve a similar problem, let’s see how to use it:
$users = collect([
['name' => 'Rosa Silva', 'team' => 'Back-end'],
['name' => 'Alberto Junior', 'team' => 'Back-end'],
['name' => 'Angela Maria', 'team' => 'Front-end'],
['name' => 'Tomas Costa', 'team' => 'Back-end'],
['name' => 'Monica Silveira', 'team' => 'Front-end'],
['name' => 'Lucia Oliveira', 'team' => 'Front-end'],
]);
$groups = $users->groupBy('team');
// {
// {
// "Back-end": [
// { "name": "Rosa Silva", "team": "Back-end" },
// { "name": "Alberto Junior", "team": "Back-end" },
// { "name": "Tomas Costa", "team": "Back-end"
// ],
// "Front-end": [
// { "name": "Angela Maria", "team": "Front-end" },
// { "name": "Monica Silveira", "team": "Front-end" },
// { "name": "Lucia Oliveira", "team": "Front-end" }
// ]
// }
// }
As a result of the groupBy()
on this collection, now we have two arrays, each one containing 3 elements, which corresponds exactly to the developers that are part of the front-end team and the other array the developers from the back-end team, as you can see, this method definitely gives you a hand when organizing your arrays.
Way cool, some valid points! I appreciate you making this article available, the rest of the site is also high quality. Have a fun.
Leave a Reply