A look at new features and improvements since the original Laravel 8.0 release: Collections

This year, the Laravel team announced a new release schedule for major Laravel versions. Instead of a major version every six months, we now get a major release every 12 months. This change didn't stop the team from improving the current release, Laravel 8. Over the last 14 months, it got so many great updates that you might have lost track of it.

I'll release a series of blog posts to highlight some of the best features and improvements since the release of v8 back in September 2020. In total, I've gathered over 100 code examples, so I'll split this blog post into five or six posts and group them by topic. Let's start with Collections!

I got most code examples and explanations from the PRs and official documentation.

v8.8.0 Added Illuminate\Collections\Traits\EnumeratesValues::pipeInto() (#34600)

The pipeInto method creates a new instance of the given class and passes the collection into the constructor:

// Before:
Category::get()->pipe(function (Collection $categories) {
return new CategoryCollection($categories);
});
 
// After:
Category::get()->pipeInto(CategoryCollection::class);

v8.16.0 Added Collections splitIn methods (#35295)

Split a collection into a certain number of groups, and fill the first groups completely.

$array = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
 
// will return 3 chunks of sizes 4, 3, and 3.
$array->splitIn(3);

v8.30.0 Added isSingle() method to Collections (#36428)

Determine if the collection contains a single element.

collect([])->isSingle(); // false
collect([1])->isSingle(); // true
collect([1, 2])->isSingle(); // false

v8.39.0 Added Illuminate\Collections\Collection::sole() method (#37034)

Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception.

$collection = collect([
['name' => 'foo'],
['name' => 'bar'],
['name' => 'bar'],
]);
 
// $result will be equal to: ['name' => 'foo']
$result = $collection->where('name', 'foo')->sole();
 
// $result will be equal to: ['name' => 'foo']
$result = $collection->sole(function ($value) {
return $value['name'] === 'foo';
});
 
// This will throw an ItemNotFoundException
$collection->where('name', 'INVALID')->sole();
 
// This will throw a MultipleItemsFoundException
$collection->where('name', 'bar')->sole();

v8.48.0 Added sliding() (#37751)

Create chunks representing a "sliding window" view of the items in the collection.

collect([1, 2, 3, 4, 5])->sliding(2);
 
// [[1, 2], [2, 3], [3, 4], [4, 5]]

v8.52.0 Allow shift() and pop() to take multiple items from a collection (#38093)

$collection = collect([1, 2, 3, 4, 5]);
 
$collection->pop(3);
// [5, 4, 3]
 
$collection->all();
// [1, 2]
$collection = collect([1, 2, 3, 4, 5]);
 
$collection->shift(3);
// [1, 2, 3]
 
$collection->all();
// [4, 5]

v8.64.0 Added Illuminate/Collections/Collection::hasAny() (#39155)

Determine if any of the keys exist in the collection.

// This example would return true:
collect(['first' => 'Hello', 'second' => 'World'])->hasAny(['first', 'fourth']);
 
// While this would return false:
collect(['first' => 'Hello', 'second' => 'World'])->hasAny(['third', 'fourth']);

In the next blog post, I'll take a look at the Database and Eloquent improvements!

Update 2022-02-07:

v8.76.2 Added doesntContain method to Collection and LazyCollection (#40044)

The inverse of the contains method, to determine whether the collection does not contain a given item.

$collection = collect([1, 2, 3, 4, 5]);
 
$collection->doesntContain(function ($value, $key) {
return $value < 5;
});
 
// false

v8.78.1 Added pipeThrough collection method (#40253)

This PR adds the pipeThrough() method for collections, allowing developers to insert an array of pipe callbacks that can manipulate the collection, carrying the return value from the previous pipe into following pipes.

$pipes = [
fn ($podcasts) => $podcasts->each(
fn ($podcast) => $podcast->process()
),
 
fn ($podcasts) => $podcasts->sum(
fn ($podcast) => $podcast->hasProcessed()
),
];
 
$processed = Podcast::all()->pipeThrough($pipes);

v8.80.0 Added a method to sort keys in a collection using a callback (#40458)

The sortKeysUsing method sorts the collection by the keys of the underlying associative array using a callback:

$collection = collect([
'ID' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
 
$collection->sortKeysUsing('strnatcasecmp');
 
/*
[
'first' => 'John',
'ID' => 22345,
'last' => 'Doe',
]
*/

v8.81.0 Added getOrPut on Collection (#40535)

Get an item from the collection by key or add it to collection if it does not exist.

// Before:
if ($collection->has($key) === false) {
$collection->put($key, $this->create($data));
}
 
return $collection->get($key);
 
// After:
$collection->getOrPut($key, fn () => $this->create($data));
 
// Or with fixed values:
$collection->getOrPut($key, $value);