Collection::reject

Removes every item for which the given callback returns true, keeping the rest.

Signature
Collection::reject(callable|mixed $callback = true): static

Parameters

ParameterTypeDescription
$$callbackoptionalcallable|mixed= trueA callback invoked as ($value, $key); items are removed when it returns true. A non-callable value removes every item loosely equal to it.

Return value

staticA new collection containing only the items the callback rejected — that is, the items for which it returned false. Original keys are preserved.

This is filter() with the truth test inverted: return true from the callback and the item is thrown away. Reaching for it is a readability decision — reject(fn ($u) => $u->banned) says what you mean far more plainly than filter(fn ($u) => ! $u->banned), and it removes a negation that is easy to misread when the condition grows.

Keys are preserved, exactly as with filter(). A list rejected down to items 0, 2 and 4 keeps those numeric keys, so json_encode() will emit a JSON object rather than an array. Chain values() before serializing or before anything that assumes a contiguous list.

The default argument catches people out. Called with no arguments, reject() compares each item loosely against true and drops everything truthy — it is a keep the falsy values operation, not the falsy-removal that the name suggests. Passing a scalar behaves the same way: reject('draft') removes every item loosely equal to 'draft', and loose comparison means 0 and '0' match each other.

The collection is never modified in place; a new instance comes back.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Drop soft-deleted or archived records from an already-loaded collection.
  • Strip empty strings and nulls out of parsed CSV rows before validating them.
  • Exclude the currently authenticated user from a list of suggested contacts.

Frequently asked questions

What is the difference between reject and filter?

They are exact inverses: filter keeps items whose callback returns true, reject discards them. Both preserve the original keys and both return a new collection.

Why does reject() with no arguments remove my truthy values?

Because the parameter defaults to true, so every item loosely equal to true is removed and only falsy items remain. To strip empties instead, use filter() with no arguments.

Do the array keys get renumbered?

No — rejected items leave gaps in the numeric keys, which makes json_encode emit an object instead of an array. Chain values() to reindex from zero before serializing.

More examples

Keys survive the rejection

The surviving items keep keys 0, 2 and 4, so json_encode produces the object {"0":90,"2":85,"4":70}. Only after values() does it serialize as the array [90,85,70] a JavaScript client expects.

Example · php
<?php

$scores = collect([90, 40, 85, 30, 70]);

$passing = $scores->reject(fn (int $s) => $s < 50);

print_r($passing->all());
echo json_encode($passing->all()), PHP_EOL;
echo json_encode($passing->values()->all()), PHP_EOL;

The bare and scalar forms

The first dump keeps only the falsy entries — NULL at key 1, int(0) at key 3 and bool(false) at key 5 — because the default argument is true, not false. The second prints Array([0] => live, [1] => archived); the comparison is loose (!=), so 0 and '0' would match one another.

Example · php
<?php

// No argument: everything loosely equal to true is removed.
var_dump(collect([1, null, 2, 0, 'a', false])->reject()->all());

// A scalar: everything loosely equal to that value is removed.
print_r(collect(['draft', 'live', 'draft', 'archived'])->reject('draft')->values()->all());

In an application: filtering an Eloquent collection

Shows the higher-order proxy form: reject->voided removes every invoice whose voided attribute is truthy, which is shorthand for reject(fn ($i) => $i->voided). Rejecting in PHP only makes sense on rows already fetched — a where clause on the query would avoid loading them at all.

Example · php
<?php

namespace App\Http\Controllers;

use App\Models\Invoice;

class StatementController extends Controller
{
    public function show()
    {
        $invoices = Invoice::forCurrentUser()->get();

        $outstanding = $invoices
            ->reject(fn (Invoice $invoice) => $invoice->isPaid())
            ->reject->voided;   // higher-order proxy on a boolean attribute

        return view('statement', ['outstanding' => $outstanding->values()]);
    }
}

Discussion

  • Be the first to comment on this lesson.