-
Notifications
You must be signed in to change notification settings - Fork 2
Collection
Viames Marino edited this page Feb 26, 2026
·
2 revisions
Pair\Orm\Collection is the in-memory collection used across Pair ORM and services.
It implements:
ArrayAccessIteratorCountable
This class is inspired by Eloquent collections, but behavior is the one implemented in Pair source code.
- Some methods return a new collection (immutable style).
- Some methods mutate the current instance and return
$this. - Methods are designed mainly for
ActiveRecord/object-like items, but many also work with arrays/scalars.
use Pair\Orm\Collection;
$orders = new Collection([
(object)['id' => 1, 'status' => 'paid', 'total' => 120.50],
(object)['id' => 2, 'status' => 'pending', 'total' => 45.00],
(object)['id' => 3, 'status' => 'paid', 'total' => 80.00],
(object)['id' => 4, 'status' => 'failed', 'total' => 10.00],
]);
$paidTotals = $orders
->whereIn('status', ['paid']) // filter
->sortBy('total') // sort ascending
->pluck('total') // get totals only
->values(); // reset numeric keys
echo $paidTotals->toJson(JSON_PRETTY_PRINT);
// [80, 120.5]-
__construct(?array $array = null)initializes items ((array)$arraycast). -
collect(): Collectionreturns a new collection with the same items. -
copy(bool $deep = false): staticshallow/deep copy; deep copy clones nested objects when possible. -
all(): arrayreturns raw internal array. -
toArray(): arrayconverts items;ActiveRecorditems are converted viatoArray(). -
toJson(int $options = 0): stringJSON-encodestoArray(). -
static wrap($value): Collectionwraps value into collection (if already collection, returns it). -
static unwrap($value): mixedreturns raw array for collection values, unchanged otherwise. -
getIterator(): \TraversablereturnsArrayIterator.
-
add(ActiveRecord $item): staticappends anActiveRecord. -
push(...$values): staticappends one or more values. -
prepend($value, $key = null): staticprepends at start; keyed prepend supported. -
unshift($value, $key = null): Collectionprepend alias with same behavior. -
put($key, $value): staticsets key/value. -
getOrPut($key, $value): mixedgets by key, sets default if missing. -
forget(int $position): staticremoves item by numeric position and reindexes keys. -
pull($key): mixedgets value then removes it viaforget(...). -
pop(int $count = 1): mixedpops last item or multiple items. -
shift(): ?ActiveRecordremoves and returns first item. -
merge(array|Collection $items): Collectionmutates current collection viaarray_merge.
-
get($key, $default = null): mixedreturns item or default. -
keys(): staticreturns collection of keys. -
values(): Collectionreturns collection with reset numeric keys. -
keyBy(string|callable $key): Collectionrekeys collection by field/callback. -
key(): intiterator current position. -
value(string $key): mixedreturns$this->first()[$key].
-
contains($key, $value = null): boolloose check by model instance or key/value. -
containsStrict($key, $value = null): boolstrict (===) version for key/value checks. -
doesntContain($key, $value = null): boolnegation ofcontains. -
containsOneItem(): booltrue when count is exactly 1. -
has($key): boolchecks key existence (single or variadic). -
hasAny(mixed $key): booltrue if any provided key exists. -
isEmpty(): booltrue when collection has no items. -
isNotEmpty(): boolinverse ofisEmpty(). -
search($value, bool $strict = false): mixedreturns key orfalse.
-
filter(?callable $callback = null): Collectionkeeps matching items; without callback removes falsy values. -
reject(callable $callback): Collectioninverse filter. -
where(string $key, $operator, $value = null): Collectioncomparison filter (=,!=,<,<=,>,>=). -
whereStrict(string $key, $operator, $value = null): Collectionstrict equality/inequality comparisons. whereIn(string $key, array $values, bool $strict = false): CollectionwhereInStrict(string $key, array $values): CollectionwhereNotIn(string $key, array $values, bool $strict = false): CollectionwhereNotInStrict(string $key, array $values): CollectionwhereBetween(string $key, array $values): CollectionwhereNotBetween(string $key, array $values): CollectionwhereNull(string $key): CollectionwhereNotNull(string $key): CollectionwhereInstanceOf(string $type): Collection-
firstWhere(string $key, $value): mixedfirst match ornull. -
before(string $key, string $value): Collectionitems where$item[$key] < $value. -
only(array $keys): Collectionkeeps only specified top-level keys. -
except(array $keys): Collectionremoves specified top-level keys.
-
first(): mixedfirst item ornull. -
firstOrFail(): mixedfirst item orPairException. -
last(): mixedlast item. -
slice(int $offset, ?int $length = null): staticslices preserving keys. -
skip(int $count): staticalias forslice($count). -
take(int $limit): staticfirst N (or last N for negative limit). -
forPage(int $page, int $perPage): Collectionoffset/limit extraction. -
nth(int $step, int $offset = 0): Collectionevery n-th element. -
chunk(int $size): Collectionsplits in fixed-size arrays. -
chunkWhile(int $size): Collectioncurrently same behavior aschunk. -
split(int $numberOfGroups): staticsplits into balanced groups.
-
map(callable $callback): staticmaps values, preserving original keys. -
transform(callable $callback): Collectionmap-like transform with explicit key passing. -
flatMap(callable $callback): Collectionmap then collapse one level. -
flatten(int $depth = INF): Collectionflattens nestedCollectionvalues. -
collapse(): Collectionmerges nested collections by one level. -
dot(): Collectionflattens nested collections while preserving composite key intent. -
pluck(string $value, ?string $key = null): Collectionextracts field values. -
append(string|array $attributes): staticcallsappend(...)on each item and returns new collection. -
groupBy(string|callable $key): Collectiongroups by field/callback. -
flip(): Collectionswaps keys and values. -
pad(int $size, $value): Collectionarray_pad behavior. -
multiply(int $times): Collectionrepeats each itemtimes. -
range(int $start, int $end): Collectionreturns integer range collection.
-
concat(array|Collection $values): Collectionappends values and returns new collection. -
combine(array $values): Collectionuses current values as keys, external values as values. intersect(array|Collection $items): CollectionintersectAssoc(array|Collection $items): Collection-
union(array|Collection $items): Collectionoriginal keys/values preserved on collisions. replace(array|Collection $items): CollectionreplaceRecursive(array|Collection $items): Collection-
zip(array|Collection $items): Collectionpairs items by index.
-
sort($callback = null)sort by callback or regular sort, keeps keys. sortBy(array|string|Closure $key, int $options = SORT_REGULAR): Collection-
sortDesc(): Collectionreverse of sorted collection. -
reverse(): staticreverse order preserving keys. -
unique(?string $key = null): Collectionunique values (or unique by key). -
uniqueStrict(): Collectionstrict unique (same implementation style asarray_unique). -
duplicates(): Collectionduplicate values. -
duplicatesStrict(): Collectionstrict duplicate comparison helper.
count(): int-
countBy(string $key): Collectionfrequency map for key values. -
sum(string $key): intsums numeric property values. -
avg(?string $key = null): floatsum / count. -
min(string $key): mixedminimum plucked value. -
mode(?string $key = null): mixedmode-like helper based on count frequencies. -
percentage(callable $callback, int $precision = 2): floatpassing percentage. reduce(callable $callback, $initial = null): mixedreduceSpread(callable $callback, array $initial): Collectionimplode(string $glue, ?string $key = null): stringjoin(string $glue, string $finalGlue = ''): string
when(bool $value, callable $callback, callable $default): mixedunless(bool $value, callable $callback, callable $default): mixedwhenEmpty(callable $callback, callable $default): mixedwhenNotEmpty(callable $callback, callable $default): mixed-
unlessEmpty(callable $callback, callable $default): mixedalias ofwhenNotEmpty. -
unlessNotEmpty(callable $callback, callable $default): mixedalias ofwhenEmpty. -
every(callable $callback): boolall items satisfy condition. -
each(callable $callback): voiditerates with item + key. -
eachSpread(callable $callback): voidspreads nested arrays into callback args. -
eachInstanceOf(string $type): voidruntime type guard on all items.
-
dump(): voidvar_dump($items). -
dd(): voiddumps then stops execution.
Iterator:
current(): mixednext(): voidrewind(): voidvalid(): boolkey(): int
ArrayAccess:
offsetExists(mixed $key): booloffsetGet($key): mixedoffsetSet($key, $value): voidoffsetUnset($key): void
-
private deepCopyValue(mixed $value): mixedrecursive helper forcopy(true). protected sortByCallback(Closure $callback): arrayprotected sortByMultiple(array $keys): arrayprotected sortBySingle(string $key, int $options, mixed $a = null, mixed $b = null): int|array
These notes reflect current source behavior:
-
random($number > 1)returns a collection of random keys, not random items. -
where(...)does not normalize two-argument syntax (where('x', 10)), it expects operator/value style. -
whereNull(...)delegates towhere($key, null)and may not behave like SQL-style null filtering. -
forget(...)reindexes numeric keys witharray_values. -
pull($key)internally callsforget(int $position); non-numeric keys can cause type issues. -
sum(...)expects property-based objects and validates key/value on first item.
Filter + aggregate:
$totalPaid = $orders
->where('status', '=', 'paid')
->sum('total');Conditional pipeline:
$result = $orders->when(
$orders->isNotEmpty(),
fn ($c) => $c->sortBy('total')->take(3),
fn ($c) => new Collection()
);Set-like operations:
$a = new Collection([1, 2, 3]);
$b = new Collection([3, 4, 5]);
$intersection = $a->intersect($b)->values(); // [3]
$union = $a->union($b); // keeps existing keys/values from $a on conflictsSee also: ActiveRecord, Query, Model, Database, Form.