Collections

Introduction

Unfortunately, PHP's support for collections is relatively incomplete. The array type is reused for multiple types, like hash tables and lists. PHP also has some support for advanced types in the SPL library, but it is incomplete, and its syntax is somewhat clunky. To cover for PHP's lack of coverage of collections, Aphiria provides simple wrappers for common collections found in most other programming languages.

Key-Value Pairs

Like its name implies, KeyValuePair holds a key and a value. Unlike key-value pairs in native PHP arrays, keys in KeyValuePair can be any value, including an object. To instantiate one, pass in the key and value:

use Aphiria\Collections\KeyValuePair;

$kvp = new KeyValuePair('thekey', 'thevalue');

KeyValuePair::key

Runtime: O(1)

To get the key-value pair's key, call

$kvp->key;

KeyValuePair::value

Runtime: O(1)

To get the key-value pair's value, call

$kvp->value;

Array Lists

Aphiria's ArrayList is probably the most similar to PHP's built-in indexed array functionality. You can instantiate one with or without an array:

use Aphiria\Collections\ArrayList;

$arrayList = new ArrayList();
// Or...
$arrayList = new ArrayList(['foo', 'bar']);

Note: ArrayList implements ArrayAccess and IteratorAggregate, so you can use array-like accessors and iterate over it.

add()

Runtime: O(1)

You can add a value via

$arrayList->add('foo');

addRange()

Runtime: O(n), n = numbers of values added

You can add multiple values at once:

$arrayList->addRange(['foo', 'bar']);

clear()

Runtime: O(1)

You can remove all values in the array list:

$arrayList->clear();

containsValue()

Runtime: O(n)

To check for a value, call

$containsValue = $arrayList->containsValue('foo');

count()

Runtime: O(1)

To grab the number of values in the array list, call

$count = $arrayList->count();

get()

Runtime: O(1)

To get the value at a certain index from an array list, call

$value = $arrayList->get(123);

If the index is out of range, an OutOfRangeException will be thrown.

indexOf()

Runtime: O(n)

To grab the index for a value, call

$index = $arrayList->indexOf('foo');

insert()

Runtime: O(1)

To insert a value at a specific index, call

$arrayList->insert(23, 'foo');

intersect()

Runtime: O(nm), n = number of values in the array list, and m = number of values in the parameter array

You can intersect an array list's values with an array by calling

$intersectedList = $arrayList->intersect(['foo', 'bar']);

removeIndex()

Runtime: O(1)

To remove a value by index, call

$arrayList->removeIndex(123);

To remove a specific value, call

$arrayList->removeValue('foo');

reverse()

Runtime: O(n)

To reverse the values in the list, call

$reversedList = $arrayList->reverse();

sort()

Runtime: O(n log n)

You can sort values similar to the way you can sort PHP arrays via usort():

$sortedList = $arrayList->sort(fn ($a, $b) => $a <=> $b);

toArray()

Runtime: O(1)

You can get the underlying array by calling

$array = $arrayList->toArray();

union()

Runtime: O(nm), n = number of values in the array list, and m = number of values in the parameter array

You can union an array list's values with an array via

$unionedList = $arrayList->union(['foo', 'bar']);

Hash Tables

Hash tables are most similar to PHP's built-in associative array functionality - they map keys to values. Unlike PHP associative arrays (which only supports scalars as keys), Aphiria's HashTables support scalars, objects, arrays, and resources as keys. You can instantiate one with or without an array of key-value pairs:

use Aphiria\Collections\HashTable;

$hashTable = new HashTable();
// Or...
$hashTable = new HashTable([new KeyValuePair('foo', 'bar')]);

Note: HashTable implements ArrayAccess and IteratorAggregate, so you can use array-like accessors and iterate over it. The keys will be numeric, and the values will be key-value pairs.

add()

Runtime: O(1)

To add a value, call

$hashTable->add('foo', 'bar');

addRange()

Runtime: O(n), n = number of values added

To add multiple values at once, pass in an array of KeyValuePair objects:

$kvps = [
    new KeyValuePair('foo', 'bar'),
    new KeyValuePair('baz', 'blah')
];
$hashTable->addRange($kvps);

clear()

Runtime: O(1)

You can remove all values:

$hashTable->clear();

containsKey()

Runtime: O(1)

To check for a value, call

$containsKey = $hashTable->containsKey('foo');

containsValue()

Runtime: O(n)

To check for a key, call

$containsValue = $hashTable->containsValue('foo');

count()

Runtime: O(1)

To get the number of values in the hash table, call

$count = $hashTable->count();

get()

Runtime: O(1)

To get a value at a key, call

$value = $hashTable->get('foo');

If the value does not exist, an OutOfBoundsException will be thrown.

getKeys()

Runtime: O(n)

You can grab all of the keys in the hash table:

$hashTable->getKeys();

getValues()

Runtime: O(n)

You can grab all of the values in the hash table:

$hashTable->getValues();

removeKey()

Runtime: O(1)

To remove a value at a certain key, call

$hashTable->removeKey('foo');

removeValue()

Runtime: O(n)

To remove a value, call

$hashTable->removeValue('foo');

toArray()

Runtime: O(n)

To get the underlying array, call

$array = $hashTable->toArray();

This will return a list of KeyValuePair - not an associative array. The reason for this is that keys can be non-strings, which is not supported in PHP.

tryGet()

Runtime: O(1)

If you would like to try to safely get a value that may or may not exist, use tryGet(). It'll return true if the key exists, otherwise false. It will also set the second parameter to the value if the key exists.

$value = null;
$exists = $hashTable->tryGet('foo', $value);

Hash Sets

Hash sets are lists with unique values. They accept objects, scalars, arrays, and resources as values. You can instantiate one with or without an array of key => value pairs:

use Aphiria\Collections\HashSet;

$set = new HashSet();
// Or...
$set = new HashSet(['foo', 'bar']);

Note: HashSet implements IteratorAggregate, so you can iterate over it.

add()

Runtime: O(1)

You can add a value via

$set->add('foo');

addRange()

Runtime: O(n), n = number of values added

You can add multiple values at once:

$set->addRange(['foo', 'bar']);

clear()

Runtime: O(1)

To remove all values in the set, call clear():

$set->clear();

containsValue()

Runtime: O(1)

To check for a value, call

$containsValue = $set->containsValue('foo');

count()

Runtime: O(1)

To grab the number of values in the hash set, call

$count = $set->count();

intersect()

Runtime: O(nm)

You can intersect a hash set with an array by calling

$intersectedSet = $set->intersect(['foo', 'bar']);

removeValue()

Runtime: O(1)

To remove a specific value, call

$set->removeValue('foo');

sort()

Runtime: O(n log n)

You can sort values similar to the way you can sort PHP arrays via usort():

$sortedSet = $set->sort(fn ($a, $b) => $a <=> $b);

toArray()

Runtime: O(n)

To get the underlying array, call

$array = $set->toArray();

union()

Runtime: O(nm)

You can union a hash set with an array via

$unionedSet = $set->union(['foo', 'bar']);

Stacks

Stacks are first-in, last-out (FILO) data structures. To create one, call

use Aphiria\Collections\Stack;

$stack = new Stack();

Note: Stack implements IteratorAggregate, so you can iterate over it.

clear()

Runtime: O(1)

To clear the values in the stack, call

$stack->clear();

containsValue()

Runtime: O(n)

To check for a value within a stack, call

$containsValue = $stack->containsValue('foo');

count()

Runtime: O(1)

To get the number of values in the stack, call

$count = $stack->count();

peek()

Runtime: O(1)

To peek at the top value in the stack, call

$value = $stack->peek();

pop()

Runtime: O(1)

To pop a value off the stack, call

$value = $stack->pop();

If there are no values in the stack, this will return null.

push()

Runtime: O(1)

To push a value onto the stack, call

$stack->push('foo');

If there are no values in the stack, this will return null.

toArray()

Runtime: O(1)

To get the underlying array, call

$array = $stack->toArray();

Queues

Queues are first-in, first-out (FIFO) data structures. To create one, call

use Aphiria\Collections\Queue;

$queue = new Queue();

Note: Queue implements IteratorAggregate, so you can iterate over it.

clear()

Runtime: O(1)

To clear the queue, call

$queue->clear();

containsValue()

Runtime: O(n)

To check for a value within a queue, call

$containsValue = $queue->containsValue('foo');

count()

Runtime: O(1)

To get the number of values in the queue, call

$count = $queue->count();

dequeue()

Runtime: O(1)

To dequeue a value from the queue, call

$value = $queue->dequeue();

If there are no values in the queue, this will return null.

enqueue()

Runtime: O(1)

To enqueue a value onto the queue, call

$queue->enqueue('foo');

peek()

Runtime: O(1)

To peek at the value at the beginning of the queue, call

$value = $queue->peek();

If there are no values in the queue, this will return null.

toArray()

Runtime: O(1)

To get the underlying array, call

$array = $queue->toArray();

Immutable Array Lists

ImmutableArrayList are read-only array lists. To instantiate one, pass in the array of values:

use Aphiria\Collections\ImmutableArrayList;

$arrayList = new ImmutableArrayList(['foo', 'bar']);

Note: ImmutableArrayList implements ArrayAccess and IteratorAggregate, so you can use array-like accessors and iterate over it.

containsValue()

Runtime: O(n)

To check for a value, call

$containsValue = $arrayList->containsValue('foo');

count()

Runtime: O(1)

To grab the number of values in the array list, call

$count = $arrayList->count();

get()

Runtime: O(1)

To get the value at a certain index from an array list, call

$value = $arrayList->get(123);

If the index is out of range, an OutOfRangeException will be thrown.

indexOf()

Runtime: O(n)

To grab the index for a value, call

$index = $arrayList->indexOf('foo');

If the array list doesn't contain the value, null will be returned.

toArray()

Runtime: O(1)

If you want to grab the underlying array, call

$array = $arrayList->toArray();

Immutable Hash Tables

Sometimes, your business logic might dictate that a hash table is read-only. Aphiria provides support via ImmutableHashTable. It requires that you pass key-value pairs into its constructor:

use Aphiria\Collections\ImmutableHashTable;

$hashTable = new ImmutableHashTable([new KeyValuePair('foo', 'bar')]);

Note: ImmutableHashTable implements ArrayAccess and IteratorAggregate, so you can use array-like accessors and iterate over it. When iterating, the keys will be numeric, and the values will be key-value pairs.

containsKey()

Runtime: O(1)

To check for a key, call

$containsKey = $hashTable->containsKey('foo');

containsValue()

Runtime: O(n)

To check for a value, call

$containsValue = $hashTable->containsValue('foo');

count()

Runtime: O(1)

To get the number of values in the hash table, call

$count = $hashTable->count();

get()

Runtime: O(1)

To get a value at a key, call

$value = $hashTable->get('foo');

If the value does not exist, an OutOfBoundsException will be thrown.

getKeys()

Runtime: O(n)

You can grab all of the keys in the hash table:

$hashTable->getKeys();

getValues()

Runtime: O(n)

You can grab all of the values in the hash table:

$hashTable->getValues();

toArray()

Runtime: O(n)

To get the underlying array, call

$array = $hashTable->toArray();

This will return a list of KeyValuePair - not an associative array. The reason for this is that keys can be non-strings (eg objects) in hash tables, but keys in PHP associative arrays must be serializable.

tryGet()

Runtime: O(1)

If you would like to try to safely get a value that may or may not exist, use tryGet(). It'll return true if the key exists, otherwise false. It will also set the second parameter to the value if the key exists.

$value = null;
$exists = $hashTable->tryGet('foo', $value);

Immutable Hash Sets

Immutable hash sets are read-only hash sets. They accept objects, scalars, arrays, and resources as values. You can instantiate one with a list of values:

use Aphiria\Collections\ImmutableHashSet;

$set = new ImmutableHashSet(['foo', 'bar']);

Note: ImmutableHashSet implements IteratorAggregate, so you can iterate over it.

containsValue()

Runtime: O(1)

To check for a value, call

$containsValue = $set->containsValue('foo');

count()

Runtime: O(1)

To grab the number of values in the set, call

$count = $set->count();

toArray()

Runtime: O(n)

To get the underlying array, call

$array = $set->toArray();