Title of the article might sound unclear, but let’s imagine you have customer list from Customer::all(), but then you need two separate lists/tables – customers from UK and from US. How to avoid two queries here? There’s a filter() function.
So, you’re doing like this as usual:
$customers = Customer::all();
And then you can filter the results, passing your own closure function to describe condition.
$uk_customers = $customers->filter(function ($customer) { return $customer->country == 'United Kingdom'; });
Now, at this point you have a new collection in $uk_customers variable, but the old $customers will remain the same, unchanged.
With this in mind, we can add another filter:
$us_customers = $customers->filter(function ($customer) { return $customer->country == 'United States'; });
So, now you have two separate lists in $uk_customers and $us_customers and you can view them in separate tables.
There’s also an opposite function called reject() – for example, if you want to keep all records EXCEPT United Kingdom, this is how it would look:
$non_uk_customers = $customers->reject(function ($customer) { return $customer->country == 'United Kingdom'; });
That’s it – another short, but useful tip.
Hi, I am new to learning Laravel.
I presume the filter function is based on code (php) processing not database query.
If the table contains a lot of records, say thousands if not millions, the penalty could be very high since DB query is surely much faster then looping all records.
So I think the filter can be ok with small table, but for large ones you better use SQL based queries.
In case I would use filter I would do this in order to optimize code:
$US_UK_costumers = DB::table(‘customers’)->where(‘country ‘, United States’) ->orWhere(‘country’, ‘United Kingdom”)->get();
and then use the filter function on a smaller number of records.
Hi Raul,
In general, you’re right, instead of Customer::all() it might make sense to filter it already upfront, like $customers = Customer::whereIn(‘country’, [‘United States’, ‘United Kingdom])->get();
And then we can use those ->filter() functions on already filtered data.
You need to elaborate on this a bit in order to explain how to pass parameters into the callback function!
See: https://stackoverflow.com/questions/24597499/laravel-passing-extra-parameter-on-collection-filtering