vrza / cardinal-collections

PHP collections toolkit

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cardinal Collections for PHP

Build Status (GitHub Actions)

A toolkit for building custom PHP collections.

Included are:

  • two fast and reusable generic iterator implementations in pure PHP

  • implementations of mutable Map and Set, but with anything as key

  • utilities for working with iterables

  • utilities for hashing arrays and objects

Map and Set features

Reduce, map and filter:

$set = new Set([1, 3, 5, 7]);
$sum = $set->reduce(function ($acc, $x) {
    return $acc + $x;
});
echo $sum;
// output: 16
$set = new Set([0, 1, 2, 3]);
$squares = $set->map(function ($x) {
    return $x * $x;
});
echo $squares;
// output: { 0, 1, 4, 9 }
$set = new Set([0, 1, 2, 3, 4, 5, 6, 7]);
$odd = $set->filter(function($x) {
    return $x % 2 == 1;
});
echo $odd;
// output: { 1, 3, 5, 7 }

Collections implement ArrayAccess, Iterator and Countable interfaces, so in many ways you can work with them like you work with standard PHP arrays:

$map[] = ['foo' => 'bar'];
$value = $map[0];
unset($map[0]);
count($map);
foreach ($map as $key => $value);

Mutations while iterating work as expected:

$set = new Set([ 1, 2, 3 ]);
$previous = false;
foreach ($set as $elem) {
    if ($previous) $set->remove($previous);
    $previous = $elem;
}
echo $set;
// output: { 3 }

map/filter/reduce are implemented as a trait that you can add to your own collections.

Comparing vanilla PHP to Cardinal Collections

Example 1

We read code that uses vanilla PHP array functions by starting from inner arguments and moving outward:

array_values(array_map(function ($cId) { return new ObjectId($cId); }, $cIds));

Cardinal Collections object-oriented approach with method chaining results in code that reads from left to right:

(new Set($cIds))->map(function ($cId) { return new ObjectId($cId); })->values();

Example 2

Vanilla PHP array_map() only maps array values:

$pidsToExitCodes = reapAnyChildren();
$jobIds = array_map(function ($pid) {
    return handleTerminatedProcess($pid);
}, array_keys($pidsToExitCodes));

Cardinal Collections Map::map() allows us to map keys and values, so we can easily refactor the above code in order to process additional information (in this example, exit codes) with no added code complexity:

$pidsToExitCodes = new Map(reapAnyChildren());
$pidsToJobIds = $pidsToExitCodes->map(function ($pid, $exitCode) {
    return [$pid, handleTerminatedProcess($pid, $exitCode)];
});

API Reference

Map

Constructor

Map(iterable $iterable = [])

Creates a new Map, initialized using keys and values from the given iterable. If called without arguments, an empty Map is created.

put

put($key, $value): Map

Adds an element to the Map. Returns the Map with the added element.

add

add($key, $value): Map

An alias for put.

putIfAbsent

putIfAbsent($key, $value)

If the key is not in the Map, adds a new key/value pair, returning null. If the key is present in the Map, returns the existing value.

append

append($value): Map

Appends a value to the Map, using the next available numeric key. Returns the Map.

remove

remove($key): Map

Removes a key from the Map, returning the Map.

delete

delete($key): Map

An alias for remove.

get

get($key, $default = null)

Returns the value associated with the key, or $default value if the key is not present in the Map.

count

count(): int

Returns the number of elements in the Map.

isEmpty

isEmpty(): bool

Returns true if the Map is empty.

nonEmpty

nonEmpty(): bool

Returns true if the Map contains at least one element.

Set

Set(iterable $iterable = [])

Creates a new Set, initialized using values of the given iterable. If called without arguments, an empty Set is created.

add

add($element): Set

Adds an element to the Set. Returns the Set with added element.

has

has($element): bool

Returns true if the element is a member of the Set.

contains

contains($element): bool

An alias for has.

remove

remove($element): Set

Removes an element from the Set, returning the Set without the element.

delete

delete($key): Set

An alias for remove.

equals

equals(Set $otherSet): bool

Returns true if Set and $otherSet are equal.

subsetOf

subsetOf(Set $otherSet): bool

Returns true if Set is a subset of $otherSet.

union

union(Set $otherSet): Set

Returns the union of Set and $otherSet.

intersect

intersect(Set $otherSet): Set

Returns the intersection of Set and $otherSet.

difference

difference(Set $otherSet): Set

Returns a new Set with all members of Set that are not members of $otherSet.

count

count(): int

Returns the number of elements in the Set.

isEmpty

isEmpty(): bool

Returns true if the Set is empty.

nonEmpty

nonEmpty(): bool

Returns true if the Set contains at least one element.

Setup

Add the following to your composer.json:

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/vrza/cardinal-collections"
        }
    ],
    "require": {
        "vrza/cardinal-collections": "dev-main"
    }
}

About

PHP collections toolkit

License:MIT License


Languages

Language:PHP 100.0%