Laravel 5 Collections: Conditionally Removing Elements From a Collection With reject

Laravel 5 Collections: Conditionally Removing Elements From a Collection With reject

Laravel 5

The reject method used to create a new Collection instance containing all the items in the collection that do not pass a given truth test. The reject method only defines one parameter: $callback. The $callback function should only have one parameter $item, which will contain the collection item under test. The $callback should return true if the item should not be included in the final collection.

To put it another way, the $callback function answers the question "Should I remove this item from the collection?"; returning true from the callback function means it will be removed while false indicates that it should remain in the collection.

The reject method does not modify the original collection instance and will return a new collection with the limited results.

Signature

public function reject(
    $callback
);

Example Use

The following code example demonstrates the usage of the reject method by rejecting any name that does not begin with the letter a (ignoring case):

use Illuminate\Support\Collection;
use Illuminate\Support\Str;

// Create a new collection instance.
$collection = new Collection([
    'Alice', 'Anna', 'Bob', 'Bev'
]);

// Only keep names that begin with the letter 'a'.
$names = $collection->reject(function($item), {
    return !Str::startsWith(Str::lower($item), 'a');
});

After the above code executes, the $names variable will be an instance of Collection and contain a value similar to the following output:

object(Illuminate\Support\Collection)
  protected 'items' => 
    array
      0 => string 'Alice'
      1 => string 'Anna' 

Using reject With Higher Order Messages

The reject method can also be used with higher order messaging, which allows us to invoke collection methods and access properties on objects using PHP's property accessors syntax. In the following example, we will create a simple Product class which will contain the name of a product, it's price, and whether it is on sale or not.

The Product Class:

class Product
{
    public $name   = '';
    public $price  = 0.0;
    public $onSale = false;

    /**
     * Determines if the product is on sale.
     *
     * @return bool
     */
    public function isOnSale() {
        return $this->onSale === true;
    }

    /**
     * Determines if the product is not on sale.
     * 
     * @return bool
     */
    public function isNotOnSale() {
        return !$this->isOnSale();
    }
}

Using the Product class, we will now create a new collection containing product instances. We will then use higher order messages to reject all of the products that are not on sale:

$products = collect([
    [
        'name'   => 'Office Chair',
        'price'  => 399.99,
        'onSale' => false
    ],
    [
        'name'   => 'Desk',
        'price'  => 199.34,
        'onSale' => true
    ]
])->transform(function ($item) {
   $product = new Product;
   $product->name   = $item['name'];
   $product->price  = $item['price'];
   $product->onSale = $item['onSale'];

   return $product;
})->reject->isNotOnSale();

After the above code has executed, the $products collection would contain only one item: the Desk, since it is currently on sale.

Start the Discussion

Leave a comment

Subscribe to our newsletter