hintik / collection
Kolekce v PHP
Requires
- php: >=8.2
Requires (Dev)
- nette/tester: ^v2.4
- nette/utils: ^3.2 || ^4
- phpstan/phpstan: ^2.0
README
PHP collection library providing immutable and mutable Abstract Data Types (ADTs): Lists, Queues, Stacks, Maps and Sets.
Requirements: PHP 8.2+
Installation
composer require hintik/collection
Overview
| ADT | Immutable | Mutable |
|---|---|---|
| List | ArrayList |
MutableArrayList |
| Map | ArrayMap |
MutableArrayMap |
| Set | HashSet |
MutableHashSet |
| Queue | ArrayQueue |
— |
| Stack | ArrayStack |
— |
All classes are in the Hintik\Collection namespace.
List
An ordered collection with positional access.
ArrayList (immutable)
use Hintik\Collection\Lists\ArrayList; $list = ArrayList::fromArray([1, 2, 3, 4, 5]); // Access $list->get(0); // 1 $list->size(); // 5 $list->contains(3); // true $list->indexOf(3); // 2 $list->lastIndexOf(2); // index of last occurrence // Functional (returns new list) $even = $list->filter(fn($v) => $v % 2 === 0); // [2, 4] $doubled = $list->map(fn($v) => $v * 2); // [2, 4, 6, 8, 10] $sorted = $list->sorted(fn($a, $b) => $a <=> $b); // [1, 2, 3, 4, 5] $rev = $list->reversed(); // [5, 4, 3, 2, 1] $unique = $list->distinct(); // removes duplicates $sub = $list->subList(1, 4); // [2, 3, 4] // Aggregation $sum = $list->reduce(fn($carry, $v) => $carry + $v, 0); // 15 $list->any(fn($v) => $v > 4); // true $list->all(fn($v) => $v > 0); // true $list->none(fn($v) => $v > 10); // true $list->first(); // 1 $list->first(fn($v) => $v > 2); // 3 $list->last(); // 5 $list->last(fn($v) => $v < 4); // 3 // Grouping $groups = $list->groupBy(fn($v) => $v % 2 === 0 ? 'even' : 'odd'); // $groups->get('even') => ArrayList([2, 4]) // Iteration $list->foreach(fn($value, $index) => print("$index: $value\n")); foreach ($list as $item) { /* ... */ }
MutableArrayList (mutable)
Has all ArrayList methods plus in-place mutation:
use Hintik\Collection\Lists\MutableArrayList; $list = MutableArrayList::fromArray([1, 2, 3]); $list->add(4); // append $list->addToIndex(1, 99); // insert at index 1 $list->addAll($other); // append all from another collection $list->set(0, 10); // replace at index $list->removeIndex(1); // remove by index $list->remove(99); // remove by value $list->removeAll($other); // remove all matching $list->sort(fn($a, $b) => $a <=> $b); // sort in place $list->reverse(); // reverse in place $list->clear();
Map
A key-value collection.
ArrayMap (immutable)
use Hintik\Collection\Map\ArrayMap; $map = ArrayMap::fromArray(['a' => 1, 'b' => 2, 'c' => 3]); // Access $map->get('a'); // 1 $map->getOrDefault('z', 0); // 0 $map->containsKey('b'); // true $map->containsValue(2); // true $map->keys()->toArray(); // ['a', 'b', 'c'] $map->values()->toArray(); // [1, 2, 3] $map->size(); // 3 // Functional (returns new map) $filtered = $map->filter(fn($v) => $v > 1); // ['b' => 2, 'c' => 3] $doubled = $map->map(fn($v) => $v * 2); // ['a' => 2, 'b' => 4, 'c' => 6] $sorted = $map->sorted(fn($a, $b) => $a <=> $b); // sorted by value $merged = $map->merge($other); // other's values win on conflict $without = $map->without('a', 'c'); // ['b' => 2] $only = $map->only('a', 'c'); // ['a' => 1, 'c' => 3] // Aggregation $sum = $map->reduce(fn($carry, $v) => $carry + $v, 0); // 6 $map->any(fn($v) => $v > 2); // true $map->all(fn($v) => $v > 0); // true $map->none(fn($v) => $v > 10); // true // Iteration $map->foreach(fn($value, $key) => print("$key: $value\n")); foreach ($map as $key => $value) { /* ... */ }
MutableArrayMap (mutable)
Has all ArrayMap methods plus in-place mutation:
use Hintik\Collection\Map\MutableArrayMap; $map = MutableArrayMap::fromEmpty(); $map->put('a', 1); // returns previous value or null $map->putAll($other); // copies all entries from another map $map->putIfAbsent('a', 9); // only adds if key not present $map->remove('a'); // returns removed value or null $map->sort(fn($a, $b) => $a <=> $b); // sort by value in place $map->clear();
Set
A collection of unique elements (strict equality).
HashSet (immutable)
use Hintik\Collection\Set\HashSet; $set = HashSet::fromArray([1, 2, 3, 2, 1]); // duplicates dropped → {1, 2, 3} $set->contains(2); // true $set->size(); // 3 // Set operations (return new set) $union = $set->union($other); // all elements from both $inter = $set->intersect($other); // elements in both $diff = $set->diff($other); // elements in $set but not in $other // Functional $even = $set->filter(fn($v) => $v % 2 === 0); $set->any(fn($v) => $v > 2); $set->all(fn($v) => $v > 0); $set->none(fn($v) => $v > 10); // Iteration foreach ($set as $item) { /* ... */ } $set->foreach(fn($item) => print($item));
MutableHashSet (mutable)
Has all HashSet methods plus mutation:
use Hintik\Collection\Set\MutableHashSet; $set = MutableHashSet::fromEmpty(); $set->add(1); // returns true if added, false if already present $set->remove(1); // returns true if removed, false if not present $set->clear();
Queue
FIFO (first-in, first-out) structure.
use Hintik\Collection\Queue\ArrayQueue; $queue = ArrayQueue::fromEmpty(); $queue->enqueue('first'); $queue->enqueue('second'); $queue->peek(); // 'first' (without removing) $queue->dequeue(); // 'first' (removes it) $queue->contains('second'); // true $queue->size(); // 1
Both dequeue() and peek() throw UnderflowException on an empty queue.
Stack
LIFO (last-in, first-out) structure.
use Hintik\Collection\Stack\ArrayStack; $stack = ArrayStack::fromEmpty(); $stack->push('first'); $stack->push('second'); $stack->peek(); // 'second' (without removing) $stack->pop(); // 'second' (removes it) $stack->contains('first'); // true $stack->size(); // 1
Both pop() and peek() throw UnderflowException on an empty stack.
Factory methods
All concrete classes provide:
| Method | Description |
|---|---|
::fromArray(array $data) |
Create from array |
::fromEmpty() |
Create empty instance |
::fromSingle($item) |
Create with one element |
Maps also provide ::fromSingle($key, $value).
Running tests
php vendor/bin/tester tests/
Static analysis
composer phpstan