Arrays
in package
Array utilities.
Table of Contents
Constants
- CHILD_FIRST : mixed = \RecursiveIteratorIterator::CHILD_FIRST
- A recursive mode that first visits leaf nodes and _then_ visits the parent node.
- DISCARD_EMPTY_ARRAYS : mixed = 1024
- Remove empty arrays when filtering recursively.
- LEAVES_ONLY : mixed = \RecursiveIteratorIterator::LEAVES_ONLY
- A recursive mode that doesn't visit intermediate nodes.
- SELF_FIRST : mixed = \RecursiveIteratorIterator::SELF_FIRST
- A recursive mode that first visits intermediate nodes and _then_ visits each child node.
Methods
- config() : array<string|int, mixed>|null
- Load a php config file.
- createMap() : array<string|int, mixed>
- Shorthand for putting together [key => value] maps.
- createMultisort() : callable(mixed, mixed): int
- Combine a set of sorts into a multisort.
- createSort() : callable(mixed, mixed): int
- Create a comparator function.
- explodeKeys() : array<string|int, mixed>
- Explode a flat array into a nested array based on the keys.
- fill() : array<string|int, mixed>
- Fill an array with the results of a callable.
- fillIntersectionKeys() : array<string|int, mixed>
- Produce a keyed set of 'keys' with values from 'array' otherwise filled with the 'fill' value.
- fillKeyed() : array<string|int, mixed>
- Fill a keyed array with the results of a callable.
- filterKeys() : array<string|int, T>
- Reduce the array to a subset, as defined by the keys parameter.
- filterRecursive() : array<string|int, T>
- Filter multi-dimensional arrays.
- find() : T|null
- Find a matching item.
- findKey() : T|null
- Find a matching item key.
- first() : T|null
- First item in the iterable.
- firstKey() : int|string|null
- Get the first key of an iterable.
- firstPair() : array<string|int, mixed>
- Get the first key + value of an iterable.
- flatten() : array<string|int, mixed>
- Flat arrays, with optional key support.
- flattenKeys() : array<string|int, mixed>
- Flatten the keys of an array with a 'glue'.
- implodeWithKeys() : string
- Join together both key and values of an array.
- indexOf() : null|int
- Find the numeric index of an associative item.
- isAssociated() : bool
- Is this an associated/keyed array.
- isNumeric() : bool
- Is this array a numeric/non-associated array.
- last() : T|null
- Last item in the iterable.
- lastKey() : int|string|null
- Get the last key of an iterable.
- lastPair() : array<string|int, mixed>
- Get the last key + value of an iterable.
- map() : array<string|int, mixed>
- A basic `array_map` that accepts iterables.
- mapKeys() : array<string|int, mixed>
- A weirder version of `mapWithKeys()`.
- mapRecursive() : array<string|int, mixed>
- A recursive version of `array_map`.
- mapWithKeys() : array<string|int, mixed>
- Like `array_map` but includes a 'key' argument.
- mergeKeyed() : array<string|int, mixed>
- Merge arrays while preserving keys.
- multisort() : void
- Multisort an array using the {@see Sortable} interface.
- multisorted() : array<string|int, T>
- Multisort an array and return it.
- normalizeOptions() : array<string|int, mixed>
- Normalise a list of options with mixed associated / values.
- reduce() : mixed
- Array reduce - with keys.
- reverse() : iterable<string|int, T>
- Create a reversed iterator of an array/traversable.
- reverseReduce() : T
- Reduce an array in reverse.
- shuffle() : array<string|int, T>
- Shuffle an array, optionally preserving the keys.
- sort() : void
- Sort an array using the {@see Sortable} interface.
- sorted() : array<string|int, T>
- Sort an array and return it.
- toArray() : array<string|int, mixed>
- Make everything an array, all the way down.
- value() : mixed
- Query an array.
- zip() : array<string|int, mixed>
- An `array_map` that accepts iterables.
Constants
CHILD_FIRST
A recursive mode that first visits leaf nodes and _then_ visits the parent node.
public
mixed
CHILD_FIRST
= \RecursiveIteratorIterator::CHILD_FIRST
DISCARD_EMPTY_ARRAYS
Remove empty arrays when filtering recursively.
public
mixed
DISCARD_EMPTY_ARRAYS
= 1024
LEAVES_ONLY
A recursive mode that doesn't visit intermediate nodes.
public
mixed
LEAVES_ONLY
= \RecursiveIteratorIterator::LEAVES_ONLY
SELF_FIRST
A recursive mode that first visits intermediate nodes and _then_ visits each child node.
public
mixed
SELF_FIRST
= \RecursiveIteratorIterator::SELF_FIRST
Methods
config()
Load a php config file.
public
static config(string $path) : array<string|int, mixed>|null
A config can be in one of two forms.
- Create a
$configvariable:
$config['key'] = 'value';
// EOF
- Or return an array:
return [
'key' => 'value',
];
Note, a missing file is indistinguishable from an invalid file. Be sure to use file_exists() first, if you care about that sort of thing.
Parameters
- $path : string
Return values
array<string|int, mixed>|null —null if the file is invalid or missing.
createMap()
Shorthand for putting together [key => value] maps.
public
static createMap(iterable<string|int, mixed> $items, string $key, string $name[, string|null $select = null ]) : array<string|int, mixed>
This will silently skip over invalid items:
- string/int/null instead of array/object
- invalid key types (int/string only)
- missing keys/names
Example:
$users = getUsers();
// Assuming users are sorted.
$options = Arrays::createMap($users, 'id', 'name', 'Choose a user');
// Hacky post-sort solution.
$options = Arrays::createMap($users, 'id', 'name');
asort($options);
$options = ['' => 'Choose a user' ] + $options;
Parameters
- $items : iterable<string|int, mixed>
- $key : string
- $name : string
- $select : string|null = null
-
Include a 'choose' option
Return values
array<string|int, mixed>createMultisort()
Combine a set of sorts into a multisort.
public
static createMultisort(array<string|int, mixed> $modes) : callable(mixed, mixed): int
Each sort can specify their mode using the options syntax. By default all sorts are ascending.
Example:
// Use default direction for all modes.
$sort = Arrays::createMultisort(['group', 'name']);
// Explicit directions per mode.
$sort = Arrays::createMultisort([
'group' => SORT_DESC,
'name' => SORT_ASC,
]);
Parameters
- $modes : array<string|int, mixed>
-
[ name => SORT ]
Return values
callable(mixed, mixed): intcreateSort()
Create a comparator function.
public
static createSort([int $dir = SORT_ASC ][, string|null $mode = null ]) : callable(mixed, mixed): int
This is compatible with the Sortable interface.
This explicitly does NOT compare objects using the natural PHP sorting behaviour, described here:
https://www.php.net/manual/en/language.oop5.object-comparison.php#98725
Given scalar values, this will use the natural ordering.
This compares array fields using array[mode] given an non-null mode.
Parameters
- $dir : int = SORT_ASC
-
SORT_ASC|SORT_DESC
- $mode : string|null = null
-
null => 'default'
Return values
callable(mixed, mixed): intexplodeKeys()
Explode a flat array into a nested array based on the keys.
public
static explodeKeys(array<string|int, mixed> $array[, string $glue = '.' ][, string|int $index = '' ]) : array<string|int, mixed>
For example:
// From this:
[ 'key.sub.value' => $item ]
// To this:
[ 'key' => [ 'sub' => [ 'value' => $item ] ] ]
Parameters
- $array : array<string|int, mixed>
- $glue : string = '.'
- $index : string|int = ''
Return values
array<string|int, mixed>fill()
Fill an array with the results of a callable.
public
static fill(int $size, callable $fn) : array<string|int, mixed>
Each index is provided as an argument.
The $index arg is a reference and can be modified to alter the key.
For a more straight-forward API, see filledKeys().
Arrays::fill(5, function(&$index) {
$index = 4 - $index;
return $index;
});
// => [4 => 0, 3 => 1, 2 => 2, 1 => 3, 0 => 4]
Parameters
- $size : int
- $fn : callable
-
(&$index) => $value
Return values
array<string|int, mixed>fillIntersectionKeys()
Produce a keyed set of 'keys' with values from 'array' otherwise filled with the 'fill' value.
public
static fillIntersectionKeys(array<string|int, mixed> $keys, array<string|int, mixed> $array[, mixed $fill = null ]) : array<string|int, mixed>
Extraneous keys within the 'array' are ignored.
For example:
$output = fillIntersectionKeys(['a', 'b'], ['b' => 1, 'c' => 2], 0);
// => ['a' => 0, 'b' => 1]
Parameters
- $keys : array<string|int, mixed>
- $array : array<string|int, mixed>
- $fill : mixed = null
Return values
array<string|int, mixed>fillKeyed()
Fill a keyed array with the results of a callable.
public
static fillKeyed(int $size, callable $fn) : array<string|int, mixed>
Each index is provided as an argument. The callable is expected to return an array pair [key, value].
Arrays::fillKeyed(5, fn($index) => [4 - $index, $index]);
// => [4 => 0, 3 => 1, 2 => 2, 1 => 3, 0 => 4]
Parameters
- $size : int
- $fn : callable
-
($index) => [$key, $value]
Return values
array<string|int, mixed>filterKeys()
Reduce the array to a subset, as defined by the keys parameter.
public
static filterKeys(array<string|int, T> $array, array<string|int, string> $keys[, bool $fill = false ]) : array<string|int, T>
Parameters
- $array : array<string|int, T>
- $keys : array<string|int, string>
- $fill : bool = false
-
Replace missing keys with null.
Tags
Return values
array<string|int, T>filterRecursive()
Filter multi-dimensional arrays.
public
static filterRecursive(array<string|int, T> $array[, callable|null $callback = null ][, int|null $mode = null ]) : array<string|int, T>
Both value and key are always passed to the callback.
If the callback is null without a specified $mode
the DISCARD_EMPTY_ARRAYS mode is implicitly active.
Be aware, numeric arrays will not 're-settle' their keys. Items will
retain their index position even with gaps from removed items. This is
the same behaviour as array_filter.
For example:
$arr = [ 'a', '', 'c' ];
$filtered = array_filter($arr);
// => [ 0 => 'a', 2 => 'c' ]
Parameters
- $array : array<string|int, T>
- $callback : callable|null = null
- $mode : int|null = null
-
LEAVES_ONLY (default), SELF_FIRST, CHILD_FIRST, DISCARD_EMPTY_ARRAYS
Tags
Return values
array<string|int, T>find()
Find a matching item.
public
static find(array<string|int, T>|iterable<string|int, T> $iterable, callable $fn) : T|null
The callable is provided with the value FIRST and the key SECOND.
// You can write:
Arrays::find($stuff, fn($item) => $item->id === 100);
// Or maybe:
Arrays::find($stuff, fn($item, key) => $key === 12 and $item->name === 12);
Parameters
- $iterable : array<string|int, T>|iterable<string|int, T>
- $fn : callable
-
($value, $key) => bool
Tags
Return values
T|nullfindKey()
Find a matching item key.
public
static findKey(array<string|int, T>|iterable<string|int, T> $iterable, callable $fn) : T|null
Same behaviour as 'find()' only this returns the index/key instead.
The callable is provided with the value FIRST and the key SECOND.
Parameters
- $iterable : array<string|int, T>|iterable<string|int, T>
- $fn : callable
-
($value, $key) => bool
Tags
Return values
T|nullfirst()
First item in the iterable.
public
static first(array<string|int, T>|iterable<string|int, T> $iterable) : T|null
Parameters
- $iterable : array<string|int, T>|iterable<string|int, T>
Tags
Return values
T|nullfirstKey()
Get the first key of an iterable.
public
static firstKey(iterable<string|int, mixed> $iterable) : int|string|null
Parameters
- $iterable : iterable<string|int, mixed>
Return values
int|string|nullfirstPair()
Get the first key + value of an iterable.
public
static firstPair(iterable<string|int, mixed> $iterable) : array<string|int, mixed>
Parameters
- $iterable : iterable<string|int, mixed>
Return values
array<string|int, mixed> —[ key, item ]
flatten()
Flat arrays, with optional key support.
public
static flatten(iterable<string|int, mixed> $array[, bool $keys = false ][, int $depth = 25 ]) : array<string|int, mixed>
Parameters
- $array : iterable<string|int, mixed>
- $keys : bool = false
- $depth : int = 25
Return values
array<string|int, mixed>flattenKeys()
Flatten the keys of an array with a 'glue'.
public
static flattenKeys(array<string|int, mixed> $array[, string $glue = '.' ]) : array<string|int, mixed>
For example:
[ 'abc' => [
'def' => 123,
'ghi' => 567,
]]
Becomes:
[
'abc.def' => 123,
'abc.ghi' => 567,
]
Parameters
- $array : array<string|int, mixed>
- $glue : string = '.'
Return values
array<string|int, mixed>implodeWithKeys()
Join together both key and values of an array.
public
static implodeWithKeys(array<string|int, mixed> $array[, string $outer_glue = '' ][, string $inner_glue = '' ]) : string
This has two glues. One for between the item (outer glue) and one for between the key and value (inner glue).
Parameters
- $array : array<string|int, mixed>
- $outer_glue : string = ''
- $inner_glue : string = ''
Return values
stringindexOf()
Find the numeric index of an associative item.
public
static indexOf(array<string|int, mixed> $array, string $key) : null|int
Parameters
- $array : array<string|int, mixed>
- $key : string
Return values
null|intisAssociated()
Is this an associated/keyed array.
public
static isAssociated(mixed $array) : bool
Opposite of isNumeric().
Parameters
- $array : mixed
Return values
boolisNumeric()
Is this array a numeric/non-associated array.
public
static isNumeric(mixed $array) : bool
Opposite of isAssociated().
Note, this exists in PHP 8.1 as array_is_list().
Parameters
- $array : mixed
Return values
boollast()
Last item in the iterable.
public
static last(array<string|int, T>|iterable<string|int, T> $iterable) : T|null
Parameters
- $iterable : array<string|int, T>|iterable<string|int, T>
Tags
Return values
T|nulllastKey()
Get the last key of an iterable.
public
static lastKey(iterable<string|int, mixed> $iterable) : int|string|null
Parameters
- $iterable : iterable<string|int, mixed>
Return values
int|string|nulllastPair()
Get the last key + value of an iterable.
public
static lastPair(iterable<string|int, mixed> $iterable) : array<string|int, mixed>
Parameters
- $iterable : iterable<string|int, mixed>
Return values
array<string|int, mixed> —[ key, item ]
map()
A basic `array_map` that accepts iterables.
public
static map(iterable<string|int, mixed> $array, callable $fn) : array<string|int, mixed>
Parameters
- $array : iterable<string|int, mixed>
- $fn : callable
-
(item) => item
Return values
array<string|int, mixed>mapKeys()
A weirder version of `mapWithKeys()`.
public
static mapKeys(iterable<string|int, mixed> $array, callable $fn) : array<string|int, mixed>
use mapWithKeys() - what a mess.
Instead this expects the callback to return a key-value pair, e.g.
Arrays::mapKeys($list, fn($item, $key) => [$key, $item]);
Parameters
- $array : iterable<string|int, mixed>
- $fn : callable
-
(item, key) => [key, item]
Return values
array<string|int, mixed>mapRecursive()
A recursive version of `array_map`.
public
static mapRecursive(array<string|int, mixed> $array, callable $fn[, int $mode = self::LEAVES_ONLY ]) : array<string|int, mixed>
Caution when using CHILD_FIRST; do not map leaves into arrays - you may
trigger an infinite recursion.
Modifying the $key callback argument, like mapWithKeys, is undefined
behaviour. Best avoid.
Parameters
- $array : array<string|int, mixed>
- $fn : callable
-
($value, $key) => $value
- $mode : int = self::LEAVES_ONLY
-
LEAVES_ONLY (default), SELF_FIRST, CHILD_FIRST
Return values
array<string|int, mixed>mapWithKeys()
Like `array_map` but includes a 'key' argument.
public
static mapWithKeys(iterable<string|int, mixed> $array, callable $fn) : array<string|int, mixed>
Key modification can be done with a reference &$key argument.
// Basic usage
Arrays::mapWithKeys($list, fn($item, $key) => $key . $item);
// OR to modify keys
Arrays::mapWithKeys($list, function($item, &$key) {
$key = $item->id;
return $item;
});
Filter callbacks used with this method can be re-used (without key
modification) for array_map or mapRecursive.
Parameters
- $array : iterable<string|int, mixed>
- $fn : callable
-
(item, key) => item
Return values
array<string|int, mixed>mergeKeyed()
Merge arrays while preserving keys.
public
static mergeKeyed(array<string|int, mixed> ...$arrays) : array<string|int, mixed>
This uses array concat instead of merge, such that:
array_merge([3 => 'one'], [3 => 'two'])
// => ['one', two']
mergeKeyed([3 => 'one'], [3 => 'two'])
// => [3 => 'two']
Parameters
- $arrays : array<string|int, mixed>
Return values
array<string|int, mixed>multisort()
Multisort an array using the {@see Sortable} interface.
public
static multisort(array<string|int, mixed> &$array, bool $preserve_keys, array<string|int, string> $modes) : void
Parameters
- $array : array<string|int, mixed>
- $preserve_keys : bool
- $modes : array<string|int, string>
-
[ name => SORT ]
Tags
multisorted()
Multisort an array and return it.
public
static multisorted(array<string|int, T> $array, bool $preserve_keys, array<string|int, string> $modes) : array<string|int, T>
Parameters
- $array : array<string|int, T>
- $preserve_keys : bool
- $modes : array<string|int, string>
-
[ name => SORT ]
Tags
Return values
array<string|int, T>normalizeOptions()
Normalise a list of options with mixed associated / values.
public
static normalizeOptions(iterable<string|int, mixed> $items, mixed $default) : array<string|int, mixed>
E.g.
$options = [
'field-1',
'field-2' => 'DESC',
'field-3',
'field-4' => 'DESC',
];
$options = Arrays::normalizeOptions($options, 'ASC');
// Returns:
[
'field-1' => 'ASC',
'field-2' => 'DESC',
'field-3' => 'ASC',
'field-4' => 'DESC',
];
Parameters
- $items : iterable<string|int, mixed>
- $default : mixed
Return values
array<string|int, mixed>reduce()
Array reduce - with keys.
public
static reduce(iterable<string|int, mixed> $iterable, callable $fn[, mixed|null $initial = null ]) : mixed
This literally identical to array_reduce except it also includes
the key value as 3rd argument to the callable.
Like this:
Arrays::reduce($list, fn($sum, $item, $key) => $sum + $key, 0);
Parameters
- $iterable : iterable<string|int, mixed>
- $fn : callable
-
(sum, item, key) => array
- $initial : mixed|null = null
reverse()
Create a reversed iterator of an array/traversable.
public
static reverse(iterable<string|int, T> $array) : iterable<string|int, T>
Iterators will likely need implement SeekableIterator.
Useful for big arrays because array_reverse() creates a copy,
whereas this one does not. Note: memory consumption is completely
untested and unfounded.
TBH not entirely sure why I wrote this.
Parameters
- $array : iterable<string|int, T>
Tags
Return values
iterable<string|int, T>reverseReduce()
Reduce an array in reverse.
public
static reverseReduce(iterable<string|int, mixed> $array, callable $fn[, T|null $initial = null ]) : T
Parameters
- $array : iterable<string|int, mixed>
- $fn : callable
-
(carry, value, key)
- $initial : T|null = null
Tags
Return values
Tshuffle()
Shuffle an array, optionally preserving the keys.
public
static shuffle(array<string|int, T>|iterable<string|int, T> $array[, bool $preserve_keys = false ]) : array<string|int, T>
Yes, this is just the native shuffle() but it's also non-destructive with key preserving options.
Parameters
- $array : array<string|int, T>|iterable<string|int, T>
- $preserve_keys : bool = false
Tags
Return values
array<string|int, T>sort()
Sort an array using the {@see Sortable} interface.
public
static sort(array<string|int, mixed> &$array[, bool $preserve_keys = false ][, int $dir = SORT_ASC ][, string|null $mode = null ]) : void
Parameters
- $array : array<string|int, mixed>
- $preserve_keys : bool = false
- $dir : int = SORT_ASC
-
SORT_ASC|SORT_DESC
- $mode : string|null = null
-
null => 'default'
sorted()
Sort an array and return it.
public
static sorted(array<string|int, T> $array[, bool $preserve_keys = false ][, int $dir = SORT_ASC ][, string|null $mode = null ]) : array<string|int, T>
Using the Sortable interface.
Parameters
- $array : array<string|int, T>
- $preserve_keys : bool = false
- $dir : int = SORT_ASC
-
SORT_ASC|SORT_DESC
- $mode : string|null = null
-
null => 'default'
Tags
Return values
array<string|int, T>toArray()
Make everything an array, all the way down.
public
static toArray(object|array<string|int, mixed> $array[, bool $recurse = true ]) : array<string|int, mixed>
This converts any nested arrayables to arrays.
Parameters
- $array : object|array<string|int, mixed>
- $recurse : bool = true
-
- recurse into nested arrays
Return values
array<string|int, mixed>value()
Query an array.
public
static value(array<string|int, mixed> $array, string $query) : mixed
It's a funny concept, but quite powerful.
For example, given an array like:
[
'items' => [
[ 'subitem' => [ 'id' => 123, 'list' => [1,2,3] ] ],
[ 'subitem' => [ 'id' => 456, 'list' => [4,5,6] ] ],
],
'options' => [
'host' => 'localhost',
'port' => 5060,
]
]
// A query `items.subitem.id` would return:
=> [ 123, 456 ]
// Or `items.subitem.list`:
=> [ [1, 2, 3], [4, 5, 6] ]
// Perhaps `options`:
=> [ 'host' => 'localhost', 'port' => '5060' ]
// And `options.host`:
=> 'localhost'
Parameters
- $array : array<string|int, mixed>
- $query : string
zip()
An `array_map` that accepts iterables.
public
static zip(iterable<string|int, mixed> ...$arrays) : array<string|int, mixed>
Parameters
- $arrays : iterable<string|int, mixed>