Array Helpers#

ArrayKit ships static helpers grouped by data shape:

  • ArraySingle for one-dimensional arrays

  • ArrayMulti for nested arrays / row collections

  • BaseArrayHelper for lower-level shared operations

  • ArraySharedOps for shared iteration/partition/skip and key-normalization internals

If you prefer one entry point, use Infocyph\ArrayKit\ArrayKit:

<?php
use Infocyph\ArrayKit\ArrayKit;

$isList = ArrayKit::single()->isList([1, 2, 3]);
$flat = ArrayKit::multi()->flatten([[1], [2, [3]]]);
$wrapped = ArrayKit::helper()->wrap('x');

Choosing the Right Helper#

Use ArraySingle when your data is a simple list or key-value map:

<?php
$tags = ['php', 'array', 'docs'];
$settings = ['env' => 'prod', 'debug' => false];

Use ArrayMulti for row sets and nested arrays:

<?php
$users = [
    ['id' => 1, 'name' => 'Alice'],
    ['id' => 2, 'name' => 'Bob'],
];

ArraySingle: Structure and Existence#

<?php
use Infocyph\ArrayKit\Array\ArraySingle;

$arr = ['name' => 'Alice', 'age' => 30];
$list = [10, 20, 30];

$exists = ArraySingle::exists($arr, 'name'); // true
$isList = ArraySingle::isList($list);         // true
$isAssoc = ArraySingle::isAssoc($arr);        // true
$isUnique = ArraySingle::isUnique([1, 2, 3]); // true

ArraySingle: Selection and Transformation#

<?php
use Infocyph\ArrayKit\Array\ArraySingle;

$arr = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];

$only = ArraySingle::only($arr, ['a', 'd']);      // ['a' => 1, 'd' => 4]
$except = ArraySingle::except($arr, ['b']);        // ['a' => 1, 'c' => 3, 'd' => 4]
$mapped = ArraySingle::map($arr, fn ($v) => $v * 10);
$filtered = ArraySingle::where($arr, fn ($v) => $v > 2);
$rejected = ArraySingle::reject($arr, fn ($v) => $v > 3);

ArraySingle: Positional Operations#

<?php
use Infocyph\ArrayKit\Array\ArraySingle;

$arr = [10, 20, 30, 40, 50, 60];

$slice = ArraySingle::slice($arr, 1, 3);            // [1 => 20, 2 => 30, 3 => 40]
$skip = ArraySingle::skip($arr, 2);                 // [2 => 30, 3 => 40, ...]
$nth = ArraySingle::nth($arr, 2);                   // [10, 30, 50]
$nthOffset = ArraySingle::nth($arr, 2, 2);          // [30, 50]
$page = ArraySingle::paginate($arr, 2, 2);          // page 2 => [2 => 30, 3 => 40]
$chunks = ArraySingle::chunk($arr, 2);              // [[10,20], [30,40], [50,60]]
$until40 = ArraySingle::skipUntil($arr, fn ($v) => $v === 40);

ArraySingle: Search, Partition, Aggregation#

<?php
use Infocyph\ArrayKit\Array\ArraySingle;

$arr = [1, 2, 2, 3, 4, 5, 'x'];

$foundKey = ArraySingle::search($arr, fn ($v) => $v === 3); // 3
$hasTwo = ArraySingle::contains($arr, 2);               // true
$hasAll = ArraySingle::containsAll($arr, [1, 2, 3]);    // true
$hasAny = ArraySingle::containsAny($arr, [99, 3]);      // true
[$even, $odd] = ArraySingle::partition($arr, fn ($v) => $v % 2 === 0);
$dupes = ArraySingle::duplicates($arr);              // [2]
$unique = ArraySingle::unique($arr);                 // [1,2,3,4,5]
$sum = ArraySingle::sum($arr);                       // 17 (non-numeric ignored)
$avg = ArraySingle::avg($arr);                       // 17/6 (non-numeric ignored)
$median = ArraySingle::median($arr);                 // 2.5
$mode = ArraySingle::mode($arr);                     // [2]

ArraySingle: Numeric and Value Helpers#

<?php
use Infocyph\ArrayKit\Array\ArraySingle;

$values = [-2, -1, 0, 1, 2, 3, 'x'];

$positive = ArraySingle::positive($values);  // [1,2,3]
$negative = ArraySingle::negative($values);  // [-2,-1]
$isInt = ArraySingle::isInt([1, 2, 3]);      // true
$isPositive = ArraySingle::isPositive([1, 2, 'x']); // true
$isNegative = ArraySingle::isNegative([-1, -2, 'x']); // true

ArrayMulti: Flattening and Shape#

<?php
use Infocyph\ArrayKit\Array\ArrayMulti;

$nested = [[1, 2], [3, [4, 5]]];

$collapse = ArrayMulti::collapse($nested);          // [1, 2, 3, [4, 5]]
$flat = ArrayMulti::flatten($nested);               // [1,2,3,4,5]
$flatZero = ArrayMulti::flatten($nested, 0);        // [[1, 2], [3, [4, 5]]]
$flatOne = ArrayMulti::flatten($nested, 1);         // flatten one level
$depth = ArrayMulti::depth($nested);                // 3
$flatByKey = ArrayMulti::flattenByKey($nested);     // flattened values

ArrayMulti: Row Filtering#

<?php
use Infocyph\ArrayKit\Array\ArrayMulti;

$rows = [
    ['name' => 'Alice', 'age' => 30, 'role' => 'admin'],
    ['name' => 'Bob', 'age' => 21, 'role' => null],
    ['name' => 'Cara', 'age' => 25, 'role' => 'editor'],
];

$adults = ArrayMulti::where($rows, 'age', '>=', 25);
$inRole = ArrayMulti::whereIn($rows, 'role', ['admin', 'editor']);
$notInRole = ArrayMulti::whereNotIn($rows, 'role', ['guest']);
$nullRole = ArrayMulti::whereNull($rows, 'role');
$notNullRole = ArrayMulti::whereNotNull($rows, 'role');
$between = ArrayMulti::between($rows, 'age', 22, 30);
$betweenAlias = ArrayMulti::whereBetween($rows, 'age', 22, 30);
$starts = ArrayMulti::whereStartsWith($rows, 'name', 'Al');
$ends = ArrayMulti::whereEndsWith($rows, 'name', 'ce');
$contains = ArrayMulti::whereContains($rows, 'name', 'li');
$like = ArrayMulti::whereLike($rows, 'name', 'A%');
$custom = ArrayMulti::whereCallback($rows, fn ($row) => $row['name'] === 'Alice');
$firstRole = ArrayMulti::firstWhereIn($rows, 'role', ['editor', 'admin']);

ArrayMulti: Grouping, Ordering, and Projection#

<?php
use Infocyph\ArrayKit\Array\ArrayMulti;

$rows = [
    ['team' => 'A', 'score' => 10],
    ['team' => 'B', 'score' => 30],
    ['team' => 'A', 'score' => 20],
];

$grouped = ArrayMulti::groupBy($rows, 'team');
$indexed = ArrayMulti::keyBy($rows, 'team');
$counts = ArrayMulti::countBy($rows, 'team');
$sorted = ArrayMulti::sortBy($rows, 'score', true);      // desc
$sortedByKey = ArrayMulti::sortBy($rows, fn ($row, $key) => $key); // callback receives row + key
$sortedMany = ArrayMulti::sortByMany($rows, [
    ['team', 'asc'],
    ['score', 'desc'],
]);
$sortedRecursive = ArrayMulti::sortRecursive($rows);
$scores = ArrayMulti::pluck($rows, 'score');             // [10,30,20]
$transposed = ArrayMulti::transpose($rows);

ArrayMulti: Row Set Operations#

<?php
use Infocyph\ArrayKit\Array\ArrayMulti;

$rows = [
    ['id' => 1, 'name' => 'A'],
    ['id' => 1, 'name' => 'A'],
    ['id' => 2, 'name' => 'B'],
];

$unique = ArrayMulti::unique($rows);
$uniqueByName = ArrayMulti::uniqueBy($rows, 'name');
$dupesByName = ArrayMulti::duplicatesBy($rows, 'name');
$minScore = ArrayMulti::min($rows, 'id');
$maxScore = ArrayMulti::max($rows, 'id');
$firstHigh = ArrayMulti::firstWhere($rows, 'id', '>=', 2);
[$passed, $failed] = ArrayMulti::partition($rows, fn ($row) => $row['id'] === 1);
$mapped = ArrayMulti::map($rows, fn ($row) => $row['name']);
$mappedKeys = ArrayMulti::mapWithKeys($rows, fn ($row) => [$row['id'] => $row['name']]);
$reduced = ArrayMulti::reduce($rows, fn ($carry, $row) => $carry + $row['id'], 0);
$sumById = ArrayMulti::sum($rows, 'id');
$sumByCallback = ArrayMulti::sum($rows, fn ($row, $key) => $row['id'] + $key);

ArrayShape Validation#

Use ArrayShape for lightweight shape assertions in row pipelines.

<?php
use Infocyph\ArrayKit\Array\ArrayShape;

$row = [
    'id' => 10,
    'email' => '[email protected]',
    'roles' => ['admin', 'editor'],
];

ArrayShape::require($row, [
    'id' => 'int',
    'email' => 'string',
    'roles' => 'list<string>',
    'nickname?' => 'string', // optional key
]);

BaseArrayHelper#

BaseArrayHelper includes shared primitives used by higher-level helpers.

<?php
use Infocyph\ArrayKit\Array\BaseArrayHelper;

$wrapped = BaseArrayHelper::wrap('x');                 // ['x']
$unwrapped = BaseArrayHelper::unWrap(['only']);        // 'only'
$accessible = BaseArrayHelper::accessible(['a' => 1]); // true

$has = BaseArrayHelper::has(['a' => 1], 'a');          // true
$hasAny = BaseArrayHelper::hasAny(['a' => 1], ['x', 'a']); // true

$range = BaseArrayHelper::range(1, 5);                 // [1,2,3,4,5]
$times = BaseArrayHelper::times(3, fn ($i) => "Row $i"); // ['Row 1','Row 2','Row 3']
$randomOne = BaseArrayHelper::random([10, 20, 30]);

$any = BaseArrayHelper::any([1, 2, 3], fn ($v) => $v > 2); // true
$all = BaseArrayHelper::all([1, 2, 3], fn ($v) => $v > 0); // true
$key = BaseArrayHelper::findKey(['x' => 3], fn ($v) => $v === 3); // x

ArraySharedOps (Internal)#

ArraySharedOps is internal infrastructure shared by ArraySingle and ArrayMulti. Prefer consuming the public helper APIs directly (ArraySingle, ArrayMulti, BaseArrayHelper).

Behavior Matrix#

Helper family

Preserves keys by default

Mutates input argument

Dot-path support

Wildcard support

ArraySingle

yes (except values(), unique(), positional list helpers)

no

no

no

ArrayMulti

usually yes for filters/sorts; reshape methods may reindex

no

no

no

DotNotation

n/a (key-path accessor)

yes for set/fill/forget via reference

yes

yes

Performance Notes#

  • Direct static calls (ArraySingle::*, ArrayMulti::*, DotNotation::*) are the fastest path.

  • ArrayKit facade and ModuleProxy add convenience but include dynamic-call overhead.

  • Collection pipeline methods mutate the current collection; use copy() / immutable() when needed.

  • Dot-notation paths are parsed and cached; escaped literal segments (for example service\\.name) are supported.

Behavior Notes#

  • Many methods preserve original keys (especially slice, where, skip variants).

  • ArraySingle::isAssoc([]) is false; empty arrays are treated as non-associative.

  • ArraySingle::nth($array, $step, $offset) starts at $offset then takes every $step item.

  • ArraySingle::unique() has loose mode (default) and strict mode.

  • ArraySingle::avg(), sum(), isPositive(), and isNegative() ignore non-numeric values.

  • ArraySingle::paginate() requires $page >= 1 and $perPage >= 1.

  • ArrayMulti::whereIn() / whereNotIn() treat null as a real value when the key exists.

  • ArrayMulti::flatten($array, 0) returns unchanged top-level values.

  • Use depthGuarded(), flattenGuarded(), and sortRecursiveGuarded() when processing untrusted/deep inputs.

  • ArrayMulti callback helpers such as sortBy(), sum(), maxBy(), minBy() support ($row, $key).

  • ArrayMulti::where() uses Infocyph\ArrayKit\compare() semantics for operators.

  • BaseArrayHelper::random() throws InvalidArgumentException when requested count exceeds array size.