Array Helpers#
ArrayKit ships static helpers grouped by data shape:
ArraySinglefor one-dimensional arraysArrayMultifor nested arrays / row collectionsBaseArrayHelperfor lower-level shared operationsArraySharedOpsfor 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
Behavior Matrix#
Helper family |
Preserves keys by default |
Mutates input argument |
Dot-path support |
Wildcard support |
|---|---|---|---|---|
|
yes (except |
no |
no |
no |
|
usually yes for filters/sorts; reshape methods may reindex |
no |
no |
no |
|
n/a (key-path accessor) |
yes for |
yes |
yes |
Performance Notes#
Direct static calls (
ArraySingle::*,ArrayMulti::*,DotNotation::*) are the fastest path.ArrayKitfacade andModuleProxyadd 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,skipvariants).ArraySingle::isAssoc([])isfalse; empty arrays are treated as non-associative.ArraySingle::nth($array, $step, $offset)starts at$offsetthen takes every$stepitem.ArraySingle::unique()has loose mode (default) and strict mode.ArraySingle::avg(),sum(),isPositive(), andisNegative()ignore non-numeric values.ArraySingle::paginate()requires$page >= 1and$perPage >= 1.ArrayMulti::whereIn()/whereNotIn()treatnullas a real value when the key exists.ArrayMulti::flatten($array, 0)returns unchanged top-level values.Use
depthGuarded(),flattenGuarded(), andsortRecursiveGuarded()when processing untrusted/deep inputs.ArrayMulticallback helpers such assortBy(),sum(),maxBy(),minBy()support($row, $key).ArrayMulti::where()usesInfocyph\ArrayKit\compare()semantics for operators.BaseArrayHelper::random()throwsInvalidArgumentExceptionwhen requested count exceeds array size.