ts/collection

Simple collection class for added type safety where needed.

Installs: 1 101

Dependents: 3

Watchers: 2

Language: PHP

v2.0.0 2014-07-28 01:04 UTC

README

Simple collection class for added type safety where needed.

Requirements

All of my components require PHP >= 5.4.

Installation

Use Composer to install: composer require ts/collection:~2.0

Using the default collection

Expected value type gets set when the first item is added to the default implementation:

use TS\Collection\Collection;

// Create collection
$coll = new Collection;

// Collection accepts only stdClass objects afterwards
$coll->add(new stdClass);

// Throws an Exception
$coll->add(new someClass);

// Create collections from arrays
$coll = Collection::fromArray([new stdClass, new stdClass]);

// Throws an Exception
$coll = Collection::fromArray([new stdClass, new someClass]);

Rolling your own: Extending the base collection

When extending the base collection class and expecting a certain type of items, set the protected $expectedType property to the fully qualified class name to declare the type your collection should accept:

class MyCollection extends TS\Collection\Collection
{
    protected $expectedType = 'stdClass';
}

$coll = new MyCollection;

// Still works fine
$coll->add(new stdClass);

// Throws an Exception
$coll->add(new someClass);

Strict typing

The collection class doesn't differentiate between base and child classes of a type by default.

To prevent child classes from being put into a collection, set the protected $mode property to one of the type safety modes defined in the TypeSafetyMode class:

use TS\Collection\Collection;
use TS\Collection\TypeSafetyMode;

class MyCollection extends Collection
{
    protected $expectedType = 'stdClass';

    protected $mode = TypeSafetyMode::STRICT;
}

// Note how this differs from the previous example:
// someClass extends stdClass this time and would be a valid parameter in the default type safety mode
class someClass extends stdClass {}

$coll = new MyCollection();

// Fine
$coll->add(new stdClass);

// Throws an Exception
$coll->add(new someClass);

Merging

use TS\Collection\Collection;

$john = (object) ['name' => 'John'];
$jane = (object) ['name' => 'Jane'];

$coll1 = new Collection;
$coll1->add($john);

$coll2 = new Collection;
$coll2->add($jane);

$merged = $coll1->mergeWith($coll2);

$merged->contains($john); // true
$merged->contains($jane); // true

Filtering

Collection::filter() expects a PHP callable with a collection item as its parameter.

use TS\Collection\Collection;

$john  = (object) ['name' => 'John'];
$james = (object) ['name' => 'James'];

$coll = new Collection;
$coll->add($john);
$coll->add($james);

$filtered = $coll->filter(
    function ($item) {
        if (strlen($item->name) <= 4) {
            return $item;
        }
    }
);

$filtered->contains($john);  // true
$filtered->contains($james); // false

Further manipulation

The collection class inherits from Doctrine's ArrayCollection, which offers even more functionality like partitioning, mapping, slicing and more, keeping the same interface, but adding type safety checks.