Resetting Laravel Collection Keys After Filtering

April 22nd, 2024

I recently filtered a Laravel collection that was due to be output as JSON. To my surprise, it didn't work as intended. Here's what happened, and how to resolve it!

First up, let's take a look at a basic filtered Collection.

$collection = collect([1, 2, 3, 4, 5]);

dd(json_encode($collection));

The result of this when using json_encode is the following:

[1,2,3,4,5]

Pretty basic stuff, and this is to be expected. However, let's filter this and see what changes.

$collection = collect([1, 2, 3, 4, 5])->filter(function ($number) {
    return $number !== 1;
});

dd(json_encode($collection));

Now, here's the result of the filtered version.

{"1":2,"2":3,"3":4,"4":5}

This can cause unintended side effects if you're passing a collection down to use in JavaScript. In my case, I was directly using the output in Alpine.js and yeah... stuff broke.

The reason for the difference in the structure of the keys in a filtered collection after we've removed an item — they're no longer sequential and therefore treated like properties and values.

The fix is pretty simple. Laravel's Collection class has a handy values method to effectively just return the values of the Collection, and therefore reset the keys back to a sequential order.

So, here's how we'd reset the collection keys after sorting.

$collection = collect([1, 2, 3, 4, 5])->filter(function ($number) {
    return $number !== 2;
})
    ->values();

dd(json_encode($collection));

And now we're back to our familiar output.

[1,3,4,5]

Next time you're doing anything to a Laravel Collection to reduce its size, reach for the values method to reset everything back to normal.

Thanks for reading! If you found this article helpful, you might enjoy our practical screencasts too.
Author
Alex Garrett-Smith
Share :

Comments

No comments, yet. Be the first to leave a comment.

Tagged under