M
MeshWorld.
Laravel Collections PHP 6 min read

Remove Elements from a Laravel Collection

Vishnu
By Vishnu
| Updated: Mar 27, 2026

Laravel Collections give you three clean ways to remove items: reject() discards items that match a condition, filter() keeps items that match a condition, and forget() removes a specific item by its key. All three work on plain array-backed collections and on Eloquent results. None of them mutate the original collection — they return a new one.

:::note[TL;DR]

  • reject(fn) removes items where the callback returns true
  • filter(fn) keeps items where the callback returns true — the inverse of reject()
  • forget($key) removes a single item by its index or key
  • All three return a new Collection; the original is unchanged
  • Works on both plain arrays and Eloquent collections :::

How does reject() work for removing items?

reject() is the direct removal tool. You pass a closure, and any item where it returns true is dropped from the result:

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

$evens = $numbers->reject(fn($value) => $value % 2 !== 0);

// Result: [2, 4, 6]

Read it like English: “reject anything that isn’t even.”

The scenario: You’re building a checkout page. Your cart collection contains products — some in stock, some not. You need to strip the out-of-stock ones before rendering the summary. reject() on stock === 0 reads clearly in a code review and does exactly what it says.

Here’s that cart example in full. The collection holds associative arrays; the callback checks the stock key:

$cart = collect([
    ['name' => 'Laptop Stand', 'price' => 29.99, 'stock' => 5],
    ['name' => 'USB Hub',      'price' => 19.99, 'stock' => 0],
    ['name' => 'Webcam',       'price' => 79.99, 'stock' => 2],
    ['name' => 'Desk Lamp',    'price' => 34.99, 'stock' => 0],
]);

$available = $cart->reject(fn($item) => $item['stock'] === 0);

// Result: Laptop Stand, Webcam

The $cart collection is untouched. $available is the new, filtered version.

How is filter() different from reject()?

filter() is the inverse. It keeps items where the callback returns true, discarding everything else. Same logic, opposite direction:

$scores = collect([45, 72, 88, 55, 91, 60]);

$passing = $scores->filter(fn($score) => $score >= 60);

// Result: [72, 88, 91, 60]

Use filter() when you’re thinking “I want the items that match X.” Use reject() when you’re thinking “I want to remove the items that match X.” They produce the same result — pick whichever makes the intent clearer at the call site.

If you call filter() with no callback, it removes all falsy values (empty strings, null, false, 0):

$mixed = collect([0, 'hello', null, false, 42, '']);

$clean = $mixed->filter();

// Result: ['hello', 42]

That zero-argument form is handy for clearing out empty form fields or nullable API values.

How do you remove a single item by key with forget()?

forget() targets a specific position. Pass it an index (for indexed arrays) or a key (for associative arrays):

$languages = collect(['PHP', 'Python', 'Ruby', 'Go']);

$languages->forget(2); // removes 'Ruby' at index 2

// Result: [0 => 'PHP', 1 => 'Python', 3 => 'Go']

Note that forget() mutates the collection in place — it’s the exception to the “returns a new collection” rule. Also note that the keys are not re-indexed after removal. If you need clean sequential keys, chain ->values() after:

$languages->forget(2)->values();

// Result: [0 => 'PHP', 1 => 'Python', 2 => 'Go']

The scenario: You’re building a tag editor. The user has a collection of tags and clicks the “X” on one of them. You know the array index from the UI. forget($index)->values() removes it and re-sequences the keys — ready to pass back to the frontend.

:::warning forget() modifies the Collection instance directly. The other methods (reject(), filter()) do not — they return a new Collection. If you’re passing a collection around and don’t expect it to change, avoid forget() or clone it first with ->collect(). :::

Does this work on Eloquent results?

Yes. An Eloquent query result is already a Collection. You can call reject(), filter(), and forget() directly:

$users = User::all();

$activeUsers = $users->reject(fn($user) => $user->is_suspended);

For large datasets, do the filtering at the query level (->where(), ->whereNull()) rather than loading all records into memory and filtering in PHP. Use collection methods when the data is already in memory or the condition can’t be expressed in SQL.

See Create a Laravel Collection from an Array if you’re working with plain arrays rather than Eloquent results.

Summary

  • reject($callback) drops items where the callback returns true. Most readable when you’re removing by a negative condition.
  • filter($callback) keeps items where the callback returns true. Pairs naturally with conditions like “give me only the active ones.”
  • filter() with no callback removes all falsy values in one step.
  • forget($key) removes by key and mutates the collection. Use ->values() after if you need re-indexed keys.
  • All collection methods work the same on Eloquent results and plain-array collections.

FAQ

Does reject() re-index the keys after removing items? No. The remaining items keep their original keys. Call ->values() to reset to sequential integer keys starting from 0.

Can I pass multiple conditions to reject()? Yes — just use logical operators inside the closure: reject(fn($item) => $item['stock'] === 0 || $item['price'] > 100).

What’s the difference between filter() with no callback and array_filter() in PHP? They behave the same — both remove falsy values. Laravel’s filter() returns a Collection; PHP’s array_filter() returns a plain array.

Can I chain reject() and filter() together? Absolutely. collect($data)->reject(...)->filter(...)->values() is valid and common. Each method returns a new Collection so chaining works naturally.

Does forget() work on string keys? Yes. $collection->forget('email') removes the email key from an associative collection just as forget(0) removes index 0 from an indexed one.