Documentation

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.

  1. Create a $config variable:
$config['key'] = 'value';
// EOF
  1. 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): int

createSort()

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): int

explodeKeys()

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
template
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
template
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
template
Return values
T|null

findKey()

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
template
Return values
T|null

first()

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
template
Return values
T|null

firstKey()

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|null

firstPair()

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
string

indexOf()

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|int

isAssociated()

Is this an associated/keyed array.

public static isAssociated(mixed $array) : bool

Opposite of isNumeric().

Parameters
$array : mixed
Return values
bool

isNumeric()

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
bool

last()

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
template
Return values
T|null

lastKey()

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|null

lastPair()

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
see
createMultisort()

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
see
createMultisort()
template
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
template
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
template
Return values
T

shuffle()

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
template
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
template
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>
Return values
array<string|int, mixed>
On this page

Search results