├── composer.json ├── renovate.json └── src ├── Collection.php ├── CollectionDecorator.php ├── Contract ├── Collection.php ├── Operation.php └── Operation │ ├── Allable.php │ ├── Appendable.php │ ├── Applyable.php │ ├── Associateable.php │ ├── AsyncMapNable.php │ ├── AsyncMapable.php │ ├── Averagesable.php │ ├── Cacheable.php │ ├── Chunkable.php │ ├── Coalesceable.php │ ├── Collapseable.php │ ├── Columnable.php │ ├── Combinateable.php │ ├── Combineable.php │ ├── Compactable.php │ ├── Comparable.php │ ├── Containsable.php │ ├── CountInAble.php │ ├── Currentable.php │ ├── Cycleable.php │ ├── Diffable.php │ ├── Diffkeysable.php │ ├── Dispersionable.php │ ├── Distinctable.php │ ├── DropWhileable.php │ ├── Dropable.php │ ├── Dumpable.php │ ├── Duplicateable.php │ ├── Entropyable.php │ ├── Equalsable.php │ ├── Everyable.php │ ├── Explodeable.php │ ├── Falsyable.php │ ├── Filterable.php │ ├── Findable.php │ ├── Firstable.php │ ├── FlatMapable.php │ ├── Flattenable.php │ ├── Flipable.php │ ├── FoldLeft1able.php │ ├── FoldLeftable.php │ ├── FoldRight1able.php │ ├── FoldRightable.php │ ├── Forgetable.php │ ├── Frequencyable.php │ ├── Getable.php │ ├── GroupByable.php │ ├── Groupable.php │ ├── Hasable.php │ ├── Headable.php │ ├── IfThenElseable.php │ ├── Implodeable.php │ ├── Initable.php │ ├── Initsable.php │ ├── Intersectable.php │ ├── Intersectkeysable.php │ ├── Intersperseable.php │ ├── IsEmptyable.php │ ├── IsNotEmptyable.php │ ├── Keyable.php │ ├── Keysable.php │ ├── Lastable.php │ ├── Limitable.php │ ├── Linesable.php │ ├── MapNable.php │ ├── Mapable.php │ ├── Matchable.php │ ├── Matchingable.php │ ├── Maxable.php │ ├── Mergeable.php │ ├── Minable.php │ ├── Normalizeable.php │ ├── Nthable.php │ ├── Nullsyable.php │ ├── Packable.php │ ├── Padable.php │ ├── Pairable.php │ ├── Partitionable.php │ ├── Permutateable.php │ ├── Pipeable.php │ ├── Pluckable.php │ ├── Prependable.php │ ├── Productable.php │ ├── RSampleable.php │ ├── Randomable.php │ ├── Rangeable.php │ ├── Reduceable.php │ ├── Reductionable.php │ ├── Rejectable.php │ ├── Reverseable.php │ ├── Sameable.php │ ├── Scaleable.php │ ├── ScanLeft1able.php │ ├── ScanLeftable.php │ ├── ScanRight1able.php │ ├── ScanRightable.php │ ├── Shuffleable.php │ ├── Sinceable.php │ ├── Sliceable.php │ ├── Sortable.php │ ├── Spanable.php │ ├── Splitable.php │ ├── Squashable.php │ ├── Strictable.php │ ├── Tailable.php │ ├── Tailsable.php │ ├── TakeWhileable.php │ ├── Tappable.php │ ├── Timesable.php │ ├── Transposeable.php │ ├── Truthyable.php │ ├── Unfoldable.php │ ├── Unlinesable.php │ ├── Unpackable.php │ ├── Unpairable.php │ ├── Untilable.php │ ├── Unwindowable.php │ ├── Unwordsable.php │ ├── Unwrapable.php │ ├── Unzipable.php │ ├── Whenable.php │ ├── Windowable.php │ ├── Wordsable.php │ ├── Wrapable.php │ └── Zipable.php ├── Iterator └── PsrCacheIterator.php ├── Operation ├── AbstractOperation.php ├── Append.php ├── Apply.php ├── Associate.php ├── AsyncMap.php ├── AsyncMapN.php ├── Averages.php ├── Cache.php ├── Chunk.php ├── Coalesce.php ├── Collapse.php ├── Column.php ├── Combinate.php ├── Combine.php ├── Compact.php ├── Compare.php ├── Contains.php ├── Current.php ├── Cycle.php ├── Diff.php ├── DiffKeys.php ├── Dispersion.php ├── Distinct.php ├── Drop.php ├── DropWhile.php ├── Dump.php ├── Duplicate.php ├── Entropy.php ├── Equals.php ├── Every.php ├── Explode.php ├── Falsy.php ├── Filter.php ├── Find.php ├── First.php ├── FlatMap.php ├── Flatten.php ├── Flip.php ├── FoldLeft.php ├── FoldLeft1.php ├── FoldRight.php ├── FoldRight1.php ├── Forget.php ├── Frequency.php ├── Get.php ├── Group.php ├── GroupBy.php ├── Has.php ├── Head.php ├── IfThenElse.php ├── Implode.php ├── Init.php ├── Inits.php ├── Intersect.php ├── IntersectKeys.php ├── Intersperse.php ├── IsEmpty.php ├── IsNotEmpty.php ├── Key.php ├── Keys.php ├── Last.php ├── Limit.php ├── Lines.php ├── Map.php ├── MapN.php ├── MatchOne.php ├── Matching.php ├── Max.php ├── Merge.php ├── Min.php ├── Normalize.php ├── Nth.php ├── Nullsy.php ├── Pack.php ├── Pad.php ├── Pair.php ├── Partition.php ├── Permutate.php ├── Pipe.php ├── Pluck.php ├── Prepend.php ├── Product.php ├── RSample.php ├── Random.php ├── Range.php ├── Reduce.php ├── Reduction.php ├── Reject.php ├── Reverse.php ├── Same.php ├── Scale.php ├── ScanLeft.php ├── ScanLeft1.php ├── ScanRight.php ├── ScanRight1.php ├── Shuffle.php ├── Since.php ├── Slice.php ├── Sort.php ├── Span.php ├── Split.php ├── Strict.php ├── Tail.php ├── Tails.php ├── TakeWhile.php ├── Tap.php ├── Times.php ├── Transpose.php ├── Truthy.php ├── Unfold.php ├── Unlines.php ├── Unpack.php ├── Unpair.php ├── Until.php ├── Unwindow.php ├── Unwords.php ├── Unwrap.php ├── Unzip.php ├── When.php ├── Window.php ├── Words.php ├── Wrap.php └── Zip.php └── Utils └── CallbacksArrayReducer.php /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": ["config:base"] 4 | } 5 | -------------------------------------------------------------------------------- /src/Contract/Operation.php: -------------------------------------------------------------------------------- 1 | : array) 21 | */ 22 | public function all(bool $normalize = true): array; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Appendable.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | public function append(mixed ...$items): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Applyable.php: -------------------------------------------------------------------------------- 1 | ): bool ...$callbacks 23 | * 24 | * @return Collection 25 | */ 26 | public function apply(callable ...$callbacks): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Associateable.php: -------------------------------------------------------------------------------- 1 | ): UKey $callbackForKeys 24 | * @param callable(T, TKey, iterable): U $callbackForValues 25 | * 26 | * @return Collection 27 | */ 28 | public function associate(?callable $callbackForKeys = null, ?callable $callbackForValues = null): Collection; 29 | } 30 | -------------------------------------------------------------------------------- /src/Contract/Operation/AsyncMapNable.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function asyncMapN(callable ...$callbacks): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/AsyncMapable.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | public function asyncMap(callable $callback): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Averagesable.php: -------------------------------------------------------------------------------- 1 | 29 | */ 30 | public function averages(): Collection; 31 | } 32 | -------------------------------------------------------------------------------- /src/Contract/Operation/Cacheable.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function cache(?CacheItemPoolInterface $cache = null): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Chunkable.php: -------------------------------------------------------------------------------- 1 | > 21 | */ 22 | public function chunk(int ...$sizes): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Coalesceable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function coalesce(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Collapseable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function collapse(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Columnable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function column(mixed $column): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Combinateable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function combinate(?int $length = null): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Combineable.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | public function combine(mixed ...$keys): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Compactable.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function compact(mixed ...$values): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Comparable.php: -------------------------------------------------------------------------------- 1 | ): T $comparator 26 | * @param V $default 27 | * 28 | * @return T|V 29 | */ 30 | public function compare(callable $comparator, mixed $default = null); 31 | } 32 | -------------------------------------------------------------------------------- /src/Contract/Operation/Containsable.php: -------------------------------------------------------------------------------- 1 | 27 | */ 28 | public function countIn(int &$counter): Collection; 29 | } 30 | -------------------------------------------------------------------------------- /src/Contract/Operation/Currentable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function cycle(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Diffable.php: -------------------------------------------------------------------------------- 1 | 26 | */ 27 | public function diff(mixed ...$values): Collection; 28 | } 29 | -------------------------------------------------------------------------------- /src/Contract/Operation/Diffkeysable.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | public function diffKeys(mixed ...$keys): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Dispersionable.php: -------------------------------------------------------------------------------- 1 | > 29 | */ 30 | public function dispersion(): Collection; 31 | } 32 | -------------------------------------------------------------------------------- /src/Contract/Operation/Distinctable.php: -------------------------------------------------------------------------------- 1 | 36 | */ 37 | public function distinct(?callable $comparatorCallback = null, ?callable $accessorCallback = null): Collection; 38 | } 39 | -------------------------------------------------------------------------------- /src/Contract/Operation/DropWhileable.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function dropWhile(callable ...$callbacks): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Dropable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function drop(int $count): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Dumpable.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function dump(string $name = '', int $size = 1, ?Closure $closure = null): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Duplicateable.php: -------------------------------------------------------------------------------- 1 | 36 | */ 37 | public function duplicate(?callable $comparatorCallback = null, ?callable $accessorCallback = null): Collection; 38 | } 39 | -------------------------------------------------------------------------------- /src/Contract/Operation/Entropyable.php: -------------------------------------------------------------------------------- 1 | |float> 35 | */ 36 | public function entropy(): Collection; 37 | } 38 | -------------------------------------------------------------------------------- /src/Contract/Operation/Equalsable.php: -------------------------------------------------------------------------------- 1 | $other 20 | */ 21 | public function equals(iterable $other): bool; 22 | } 23 | -------------------------------------------------------------------------------- /src/Contract/Operation/Everyable.php: -------------------------------------------------------------------------------- 1 | ): bool ...$callbacks 19 | */ 20 | public function every(callable ...$callbacks): bool; 21 | } 22 | -------------------------------------------------------------------------------- /src/Contract/Operation/Explodeable.php: -------------------------------------------------------------------------------- 1 | > 23 | */ 24 | public function explode(mixed ...$explodes): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Falsyable.php: -------------------------------------------------------------------------------- 1 | ): bool ...$callbacks 21 | * 22 | * @return Collection 23 | */ 24 | public function filter(callable ...$callbacks): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Findable.php: -------------------------------------------------------------------------------- 1 | ): bool) ...$callbacks 23 | * 24 | * @return T|V 25 | */ 26 | public function find(mixed $default = null, callable ...$callbacks); 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Firstable.php: -------------------------------------------------------------------------------- 1 | ): iterable $callback 25 | * 26 | * @return Collection 27 | */ 28 | public function flatMap(callable $callback): Collection; 29 | } 30 | -------------------------------------------------------------------------------- /src/Contract/Operation/Flattenable.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function flatten(int $depth = PHP_INT_MAX): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Flipable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function flip(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/FoldLeft1able.php: -------------------------------------------------------------------------------- 1 | ): V $callback 22 | * 23 | * @return V 24 | */ 25 | public function foldLeft1(callable $callback): mixed; 26 | } 27 | -------------------------------------------------------------------------------- /src/Contract/Operation/FoldLeftable.php: -------------------------------------------------------------------------------- 1 | ): V $callback 22 | * @param V $initial 23 | * 24 | * @return V 25 | */ 26 | public function foldLeft(callable $callback, mixed $initial); 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/FoldRight1able.php: -------------------------------------------------------------------------------- 1 | ): V $callback 17 | * 18 | * @return V 19 | */ 20 | public function foldRight1(callable $callback): mixed; 21 | } 22 | -------------------------------------------------------------------------------- /src/Contract/Operation/FoldRightable.php: -------------------------------------------------------------------------------- 1 | ): V $callback 22 | * @param V $initial 23 | * 24 | * @return V 25 | */ 26 | public function foldRight(callable $callback, mixed $initial): mixed; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Forgetable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function forget(mixed ...$keys): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Frequencyable.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function frequency(): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Getable.php: -------------------------------------------------------------------------------- 1 | > 26 | */ 27 | public function groupBy(callable $callback): Collection; 28 | } 29 | -------------------------------------------------------------------------------- /src/Contract/Operation/Groupable.php: -------------------------------------------------------------------------------- 1 | > 22 | */ 23 | public function group(): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Hasable.php: -------------------------------------------------------------------------------- 1 | ): T ...$callbacks 19 | */ 20 | public function has(callable ...$callbacks): bool; 21 | } 22 | -------------------------------------------------------------------------------- /src/Contract/Operation/Headable.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function ifThenElse(callable $condition, callable $then, ?callable $else = null): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Implodeable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function init(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Initsable.php: -------------------------------------------------------------------------------- 1 | > 21 | */ 22 | public function inits(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Intersectable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function intersect(mixed ...$values): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Intersectkeysable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function intersectKeys(mixed ...$keys): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Intersperseable.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | public function intersperse(mixed $element, int $every = 1, int $startAt = 0): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/IsEmptyable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function keys(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Lastable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function limit(int $count = -1, int $offset = 0): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Linesable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function lines(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/MapNable.php: -------------------------------------------------------------------------------- 1 | ): mixed ...$callbacks 21 | * 22 | * @return Collection 23 | */ 24 | public function mapN(callable ...$callbacks): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Mapable.php: -------------------------------------------------------------------------------- 1 | ): U $callback 23 | * 24 | * @return Collection 25 | */ 26 | public function map(callable $callback): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Matchable.php: -------------------------------------------------------------------------------- 1 | ): bool $callback 27 | * @param null|callable(T, TKey, iterable): bool $matcher 28 | */ 29 | public function match(callable $callback, ?callable $matcher = null): bool; 30 | } 31 | -------------------------------------------------------------------------------- /src/Contract/Operation/Matchingable.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function matching(Criteria $criteria): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Maxable.php: -------------------------------------------------------------------------------- 1 | ...$sources 23 | * 24 | * @return Collection 25 | */ 26 | public function merge(iterable ...$sources): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Minable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function normalize(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Nthable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function nth(int $step, int $offset = 0): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Nullsyable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function pack(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Padable.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | public function pad(int $size, mixed $value): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Pairable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function pair(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Partitionable.php: -------------------------------------------------------------------------------- 1 | ): bool ...$callbacks 25 | * 26 | * @return CollectionInterface> 27 | */ 28 | public function partition(callable ...$callbacks): CollectionInterface; 29 | } 30 | -------------------------------------------------------------------------------- /src/Contract/Operation/Permutateable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function permutate(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Pipeable.php: -------------------------------------------------------------------------------- 1 | ): iterable ...$callbacks 23 | * 24 | * @return Collection 25 | */ 26 | public function pipe(callable ...$callbacks): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Pluckable.php: -------------------------------------------------------------------------------- 1 | |array-key $pluck 22 | * 23 | * @return Collection|T> 24 | */ 25 | public function pluck(mixed $pluck, mixed $default = null): Collection; 26 | } 27 | -------------------------------------------------------------------------------- /src/Contract/Operation/Prependable.php: -------------------------------------------------------------------------------- 1 | 25 | */ 26 | public function prepend(mixed ...$items): Collection; 27 | } 28 | -------------------------------------------------------------------------------- /src/Contract/Operation/Productable.php: -------------------------------------------------------------------------------- 1 | ...$iterables 24 | * 25 | * @return Collection> 26 | */ 27 | public function product(iterable ...$iterables): Collection; 28 | } 29 | -------------------------------------------------------------------------------- /src/Contract/Operation/RSampleable.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function rsample(float $probability): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Randomable.php: -------------------------------------------------------------------------------- 1 | 24 | */ 25 | public function random(int $size = 1, ?int $seed = null): Collection; 26 | } 27 | -------------------------------------------------------------------------------- /src/Contract/Operation/Rangeable.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | public static function range(float $start = 0.0, float $end = INF, float $step = 1.0): Collection; 21 | } 22 | -------------------------------------------------------------------------------- /src/Contract/Operation/Reduceable.php: -------------------------------------------------------------------------------- 1 | ): V $callback 21 | * @param V $initial 22 | * 23 | * @return V 24 | */ 25 | public function reduce(callable $callback, mixed $initial = null); 26 | } 27 | -------------------------------------------------------------------------------- /src/Contract/Operation/Reductionable.php: -------------------------------------------------------------------------------- 1 | ): V $callback 23 | * @param V $initial 24 | * 25 | * @return Collection 26 | */ 27 | public function reduction(callable $callback, mixed $initial = null): Collection; 28 | } 29 | -------------------------------------------------------------------------------- /src/Contract/Operation/Rejectable.php: -------------------------------------------------------------------------------- 1 | ): bool ...$callbacks 21 | * 22 | * @return Collection 23 | */ 24 | public function reject(callable ...$callbacks): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Reverseable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function reverse(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Sameable.php: -------------------------------------------------------------------------------- 1 | $other 26 | * @param null|callable(mixed, mixed): (Closure(mixed, mixed): bool) $comparatorCallback 27 | */ 28 | public function same(iterable $other, ?callable $comparatorCallback = null): bool; 29 | } 30 | -------------------------------------------------------------------------------- /src/Contract/Operation/Scaleable.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function scale( 24 | float $lowerBound, 25 | float $upperBound, 26 | float $wantedLowerBound = 0.0, 27 | float $wantedUpperBound = 1.0, 28 | float $base = 0.0 29 | ): Collection; 30 | } 31 | -------------------------------------------------------------------------------- /src/Contract/Operation/ScanLeft1able.php: -------------------------------------------------------------------------------- 1 | ): (T|V) $callback 25 | * 26 | * @return Collection 27 | */ 28 | public function scanLeft1(callable $callback): Collection; 29 | } 30 | -------------------------------------------------------------------------------- /src/Contract/Operation/ScanLeftable.php: -------------------------------------------------------------------------------- 1 | ): V $callback 25 | * @param V $initial 26 | * 27 | * @return Collection 28 | */ 29 | public function scanLeft(callable $callback, mixed $initial): Collection; 30 | } 31 | -------------------------------------------------------------------------------- /src/Contract/Operation/ScanRight1able.php: -------------------------------------------------------------------------------- 1 | ): (T|V) $callback 26 | * 27 | * @return Collection 28 | */ 29 | public function scanRight1(callable $callback): Collection; 30 | } 31 | -------------------------------------------------------------------------------- /src/Contract/Operation/ScanRightable.php: -------------------------------------------------------------------------------- 1 | ): V $callback 25 | * @param V $initial 26 | * 27 | * @return Collection 28 | */ 29 | public function scanRight(callable $callback, mixed $initial): Collection; 30 | } 31 | -------------------------------------------------------------------------------- /src/Contract/Operation/Shuffleable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function shuffle(?int $seed = null): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Sinceable.php: -------------------------------------------------------------------------------- 1 | ):bool ...$callbacks 21 | * 22 | * @return Collection 23 | */ 24 | public function since(callable ...$callbacks): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Sliceable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function slice(int $offset, int $length = -1): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Sortable.php: -------------------------------------------------------------------------------- 1 | 30 | */ 31 | public function sort(int $type = Sortable::BY_VALUES, null|callable|Closure $callback = null): Collection; 32 | } 33 | -------------------------------------------------------------------------------- /src/Contract/Operation/Spanable.php: -------------------------------------------------------------------------------- 1 | ): bool ...$callbacks 26 | * 27 | * @return CollectionInterface> 28 | */ 29 | public function span(callable ...$callbacks): CollectionInterface; 30 | } 31 | -------------------------------------------------------------------------------- /src/Contract/Operation/Splitable.php: -------------------------------------------------------------------------------- 1 | > 30 | */ 31 | public function split(int $type = Splitable::BEFORE, callable ...$callbacks): Collection; 32 | } 33 | -------------------------------------------------------------------------------- /src/Contract/Operation/Squashable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function squash(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Strictable.php: -------------------------------------------------------------------------------- 1 | 27 | */ 28 | public function strict(?callable $callback = null): Collection; 29 | } 30 | -------------------------------------------------------------------------------- /src/Contract/Operation/Tailable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function tail(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Tailsable.php: -------------------------------------------------------------------------------- 1 | > 22 | */ 23 | public function tails(): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/TakeWhileable.php: -------------------------------------------------------------------------------- 1 | ): bool ...$callbacks 22 | * 23 | * @return Collection 24 | */ 25 | public function takeWhile(callable ...$callbacks): Collection; 26 | } 27 | -------------------------------------------------------------------------------- /src/Contract/Operation/Tappable.php: -------------------------------------------------------------------------------- 1 | ): void ...$callbacks 22 | * 23 | * @return Collection 24 | */ 25 | public function tap(callable ...$callbacks): Collection; 26 | } 27 | -------------------------------------------------------------------------------- /src/Contract/Operation/Timesable.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public static function times(int $number = 0, ?callable $callback = null): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Transposeable.php: -------------------------------------------------------------------------------- 1 | > 21 | */ 22 | public function transpose(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Truthyable.php: -------------------------------------------------------------------------------- 1 | $callback 19 | * @param iterable $parameters 20 | * 21 | * @return Collection> 22 | */ 23 | public static function unfold(callable $callback, iterable $parameters = []): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Unlinesable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function unpack(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Unpairable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function unpair(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Untilable.php: -------------------------------------------------------------------------------- 1 | ):bool ...$callbacks 21 | * 22 | * @return Collection 23 | */ 24 | public function until(callable ...$callbacks): Collection; 25 | } 26 | -------------------------------------------------------------------------------- /src/Contract/Operation/Unwindowable.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function unwindow(): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Unwordsable.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function unwrap(): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Unzipable.php: -------------------------------------------------------------------------------- 1 | > 21 | */ 22 | public function unzip(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Whenable.php: -------------------------------------------------------------------------------- 1 | ): bool $predicate 25 | * @param callable(iterable): iterable $whenTrue 26 | * @param callable(iterable): iterable $whenFalse 27 | * 28 | * @return Collection 29 | */ 30 | public function when(callable $predicate, callable $whenTrue, ?callable $whenFalse = null): Collection; 31 | } 32 | -------------------------------------------------------------------------------- /src/Contract/Operation/Windowable.php: -------------------------------------------------------------------------------- 1 | > 22 | */ 23 | public function window(int $size): Collection; 24 | } 25 | -------------------------------------------------------------------------------- /src/Contract/Operation/Wordsable.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | public function words(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Wrapable.php: -------------------------------------------------------------------------------- 1 | > 21 | */ 22 | public function wrap(): Collection; 23 | } 24 | -------------------------------------------------------------------------------- /src/Contract/Operation/Zipable.php: -------------------------------------------------------------------------------- 1 | ...$iterables 24 | * 25 | * @return Collection, list> 26 | */ 27 | public function zip(iterable ...$iterables): Collection; 28 | } 29 | -------------------------------------------------------------------------------- /src/Operation/AbstractOperation.php: -------------------------------------------------------------------------------- 1 | __invoke(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Operation/Append.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @param array $items 29 | * 30 | * @return Closure(iterable): Generator 31 | */ 32 | static fn (array $items): Closure => 33 | /** 34 | * @param iterable $iterable 35 | * 36 | * @return Generator 37 | */ 38 | static fn (iterable $iterable): Generator => yield from new ConcatIterableAggregate([$iterable, $items]); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Operation/Apply.php: -------------------------------------------------------------------------------- 1 | ):bool ...): Closure(iterable): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @param callable(T, TKey, iterable): bool ...$callbacks 26 | * 27 | * @return Closure(iterable): Generator 28 | */ 29 | static fn (callable ...$callbacks): Closure => 30 | /** 31 | * @param iterable $iterable 32 | * 33 | * @return Generator 34 | */ 35 | static function (iterable $iterable) use ($callbacks): Generator { 36 | foreach ($iterable as $key => $value) { 37 | foreach ($callbacks as $cKey => $callback) { 38 | if (false === $callback($value, $key, $iterable)) { 39 | unset($callbacks[$cKey]); 40 | } 41 | } 42 | 43 | yield $key => $value; 44 | } 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Operation/Averages.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator $pipe */ 24 | $pipe = (new Pipe())()( 25 | (new Normalize())(), 26 | (new ScanLeft1())()( 27 | static fn (float $acc, float $value, int $key): float => ($acc * $key + $value) / ($key + 1) 28 | ) 29 | ); 30 | 31 | return $pipe; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Operation/Cache.php: -------------------------------------------------------------------------------- 1 | ): Generator 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @return Closure(iterable): Generator 29 | */ 30 | static fn (CacheItemPoolInterface $cache): Closure => 31 | /** 32 | * @param iterable $iterable 33 | * 34 | * @return Generator 35 | */ 36 | static fn (iterable $iterable): Generator => yield from new PsrCacheIterator((new IterableIteratorAggregate($iterable))->getIterator(), $cache); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Operation/Coalesce.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator $pipe */ 24 | $pipe = (new Pipe())()( 25 | (new Compact())()([]), 26 | (new Head())(), 27 | ); 28 | 29 | // Point free style. 30 | return $pipe; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Operation/Collapse.php: -------------------------------------------------------------------------------- 1 | )>): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | $filterCallback = 24 | /** 25 | * @param T $value 26 | */ 27 | static fn (mixed $value): bool => is_iterable($value); 28 | 29 | /** @var Closure(iterable)>): Generator $pipe */ 30 | $pipe = (new Pipe())()( 31 | (new Filter())()($filterCallback), 32 | (new Flatten())()(1), 33 | ); 34 | 35 | // Point free style. 36 | return $pipe; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Operation/Column.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @return Closure(iterable): Generator 26 | */ 27 | static function (mixed $column): Closure { 28 | $filterCallbackBuilder = 29 | /** 30 | * @param T $value 31 | * @param TKey $key 32 | */ 33 | static fn (mixed $value, mixed $key): bool => $key === $column; 34 | 35 | /** @var Closure(iterable): Generator $pipe */ 36 | $pipe = (new Pipe())()( 37 | (new Transpose())(), 38 | (new Filter())()($filterCallbackBuilder), 39 | (new Head())(), 40 | (new Flatten())()(1) 41 | ); 42 | 43 | // Point free style. 44 | return $pipe; 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Operation/Combine.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator 24 | */ 25 | public function __invoke(): Closure 26 | { 27 | return 28 | /** 29 | * @param array $keys 30 | * 31 | * @return Closure(iterable): Generator 32 | */ 33 | static function (array $keys): Closure { 34 | $buildMultipleIterable = 35 | /** 36 | * @param iterable $iterable 37 | */ 38 | static fn (iterable $iterable): Generator => yield from new MultipleIterableAggregate([$keys, $iterable], MultipleIterator::MIT_NEED_ANY); 39 | 40 | /** @var Closure(iterable): Generator $pipe */ 41 | $pipe = (new Pipe())()( 42 | $buildMultipleIterable, 43 | (new Flatten())()(1), 44 | (new Pair())(), 45 | ); 46 | 47 | // Point free style. 48 | return $pipe; 49 | }; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Operation/Compact.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param array $values 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static function (array $values): Closure { 32 | $filterCallback = 33 | /** 34 | * @param non-empty-array $values 35 | */ 36 | static fn (array $values): Closure => 37 | /** 38 | * @param T $value 39 | */ 40 | static fn (mixed $value): bool => !in_array($value, $values, true); 41 | 42 | return (new Filter())()( 43 | $filterCallback( 44 | [] === $values ? 45 | Nullsy::VALUES : 46 | $values 47 | ) 48 | ); 49 | }; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Operation/Compare.php: -------------------------------------------------------------------------------- 1 | ): T): Closure(iterable): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @param callable(T, T, TKey, iterable): T $comparator 26 | * 27 | * @return Closure(iterable): Generator 28 | */ 29 | static function (callable $comparator): Closure { 30 | /** @var Closure(iterable): Generator $foldLeft1 */ 31 | $foldLeft1 = (new FoldLeft1())()($comparator); 32 | 33 | // Point free style. 34 | return $foldLeft1; 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Operation/Contains.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param array $values 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static fn (array $values): Closure => (new MatchOne())()(static fn (): bool => true)( 32 | /** 33 | * @param T $value 34 | */ 35 | static fn (mixed $value): bool => in_array($value, $values, true) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Operation/Current.php: -------------------------------------------------------------------------------- 1 | ): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @return Closure(V): Closure(iterable): Generator 28 | */ 29 | static fn (int $index): Closure => 30 | /** 31 | * @param V $default 32 | * 33 | * @return Closure(iterable): Generator 34 | */ 35 | static function (mixed $default) use ($index): Closure { 36 | /** @var Closure(iterable): Generator $pipe */ 37 | $pipe = (new Pipe())()( 38 | (new Normalize())(), 39 | (new Get())()($index)($default) 40 | ); 41 | 42 | // Point free style. 43 | return $pipe; 44 | }; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Operation/Cycle.php: -------------------------------------------------------------------------------- 1 | ): iterable 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param iterable $iterable 27 | * 28 | * @return iterable 29 | */ 30 | static function (iterable $iterable): iterable { 31 | yield from new InfiniteIteratorAggregate((new IterableIteratorAggregate($iterable))->getIterator()); 32 | }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Operation/Diff.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param array $values 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static fn (array $values): Closure => (new Filter())()( 32 | /** 33 | * @param T $value 34 | */ 35 | static fn (mixed $value): bool => !in_array($value, $values, true) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Operation/DiffKeys.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param array $keys 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static fn (array $keys): Closure => (new Filter())()( 32 | /** 33 | * @param T $value 34 | * @param TKey $key 35 | */ 36 | static fn (mixed $value, mixed $key): bool => !in_array($key, $keys, true) 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Operation/Dispersion.php: -------------------------------------------------------------------------------- 1 | ): Generator> 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator> $pipe */ 24 | $pipe = (new Pipe())()( 25 | (new Normalize())(), 26 | (new ScanLeft())()( 27 | /** 28 | * @param array, T> $acc 29 | * @param T $value 30 | * 31 | * @return list{float|int<0,1>, T} 32 | */ 33 | static function (array $acc, mixed $value, int $key): array { 34 | [$c, $v] = $acc; 35 | 36 | return [(0 === $key) ? 0 : (($c * ($key - 1) + (($v === $value) ? 0 : 1)) / $key), $value]; 37 | } 38 | )([0, null]), 39 | (new Drop())()(1), 40 | (new Map())()( 41 | /** 42 | * @param array, T> $value 43 | * 44 | * @return float|int<0,1> 45 | */ 46 | static fn (array $value): float|int => (0.0 === $value[0] || 1.0 === $value[0]) ? (int) $value[0] : $value[0] 47 | ) 48 | ); 49 | 50 | return $pipe; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Operation/Drop.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return (new Limit())()(-1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Operation/DropWhile.php: -------------------------------------------------------------------------------- 1 | ): bool ...): Closure(iterable): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param callable(T, TKey, iterable):bool ...$callbacks 27 | * 28 | * @return Closure(iterable): Generator 29 | */ 30 | static fn (callable ...$callbacks): Closure => 31 | /** 32 | * @param iterable $iterable 33 | * 34 | * @return Generator 35 | */ 36 | static function (iterable $iterable) use ($callbacks): Generator { 37 | $skip = false; 38 | $callback = CallbacksArrayReducer::or()($callbacks); 39 | 40 | foreach ($iterable as $key => $current) { 41 | if (false === $skip) { 42 | if (false === $callback($current, $key, $iterable)) { 43 | $skip = true; 44 | 45 | yield $key => $current; 46 | } 47 | 48 | continue; 49 | } 50 | 51 | yield $key => $current; 52 | } 53 | }; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Operation/Every.php: -------------------------------------------------------------------------------- 1 | ): bool): Closure(iterable): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param callable(int, T, TKey, iterable): bool ...$predicates 27 | * 28 | * @return Closure(iterable): Generator 29 | */ 30 | static fn (callable ...$predicates): Closure => static function (iterable $iterable) use ($predicates): Generator { 31 | $predicate = CallbacksArrayReducer::or()($predicates); 32 | 33 | /** @var Generator $packed */ 34 | $packed = (new Pack())()($iterable); 35 | 36 | foreach ($packed as $index => [$key, $value]) { 37 | if (false === $predicate($index, $value, $key, $iterable)) { 38 | return yield $index => false; 39 | } 40 | } 41 | 42 | yield true; 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Operation/Explode.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator> 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param array $explodes 27 | * 28 | * @return Closure(iterable): Generator> 29 | */ 30 | static function (array $explodes): Closure { 31 | /** @var Closure(iterable): Generator> $split */ 32 | $split = (new Split())()(Splitable::REMOVE)( 33 | ...array_map( 34 | /** 35 | * @param T $explode 36 | */ 37 | static fn (mixed $explode): Closure => 38 | /** 39 | * @param T $value 40 | */ 41 | static fn (mixed $value): bool => $value === $explode, 42 | $explodes 43 | ) 44 | ); 45 | 46 | // Point free style. 47 | return $split; 48 | }; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Operation/Falsy.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return (new Every())()( 24 | /** 25 | * @param T $value 26 | */ 27 | static fn (int $index, mixed $value): bool => !(bool) $value 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Operation/Find.php: -------------------------------------------------------------------------------- 1 | ): bool ...): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param V $default 28 | * 29 | * @return Closure(callable(T, TKey, iterable): bool ...): Closure(iterable): Generator 30 | */ 31 | static fn (mixed $default): Closure => 32 | /** 33 | * @param callable(T, TKey, iterable): bool ...$callbacks 34 | * 35 | * @return Closure(iterable): Generator 36 | */ 37 | static function (callable ...$callbacks) use ($default): Closure { 38 | /** @var Closure(iterable): Generator $pipe */ 39 | $pipe = (new Pipe())()( 40 | (new Filter())()(...$callbacks), 41 | (new Current())()(0)($default) 42 | ); 43 | 44 | // Point free style. 45 | return $pipe; 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Operation/First.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return (new Head())(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Operation/FlatMap.php: -------------------------------------------------------------------------------- 1 | ): iterable): Closure(iterable): Generator 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @param callable(T, TKey, iterable): iterable $callback 29 | */ 30 | static function (callable $callback): Closure { 31 | /** @var Closure(iterable): Generator $flatMap */ 32 | $flatMap = (new Pipe())()( 33 | (new Map())()($callback), 34 | (new Flatten())()(1), 35 | ); 36 | 37 | // Point free style 38 | return $flatMap; 39 | }; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Operation/Flatten.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @return Closure(iterable): Generator 26 | */ 27 | static fn (int $depth): Closure => 28 | /** 29 | * @param iterable $iterable 30 | */ 31 | static function (iterable $iterable) use ($depth): Generator { 32 | foreach ($iterable as $key => $value) { 33 | if (!is_iterable($value)) { 34 | yield $key => $value; 35 | 36 | continue; 37 | } 38 | 39 | yield from (1 !== $depth) 40 | ? (new Flatten())()($depth - 1)($value) 41 | : $value; 42 | } 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Operation/Flip.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return (new Associate())()( 24 | /** 25 | * @param TKey $key 26 | * @param T $value 27 | * 28 | * @return T 29 | */ 30 | static fn (mixed $key, mixed $value): mixed => $value 31 | )( 32 | /** 33 | * @param T $value 34 | * @param TKey $key 35 | * 36 | * @return TKey 37 | */ 38 | static fn (mixed $value, mixed $key): mixed => $key 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Operation/FoldLeft.php: -------------------------------------------------------------------------------- 1 | ): V): Closure(V): Closure(iterable): Generator 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @param callable(V, T, TKey, iterable): V $callback 29 | * 30 | * @return Closure(V): Closure(iterable): Generator 31 | */ 32 | static fn (callable $callback): Closure => 33 | /** 34 | * @param V $initial 35 | * 36 | * @return Closure(iterable): Generator 37 | */ 38 | static fn (mixed $initial): Closure => 39 | /** 40 | * @param iterable $iterable 41 | * 42 | * @return Generator 43 | */ 44 | static fn (iterable $iterable): Generator => yield from new ReduceIterableAggregate($iterable, Closure::fromCallable($callback), $initial); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Operation/FoldLeft1.php: -------------------------------------------------------------------------------- 1 | ): V): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param callable((T|V), T, TKey, iterable): V $callback 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static function (callable $callback): Closure { 32 | /** @var Closure(iterable):(Generator) $pipe */ 33 | $pipe = (new Pipe())()( 34 | (new ScanLeft1())()($callback), 35 | (new Last())() 36 | ); 37 | 38 | // Point free style. 39 | return $pipe; 40 | }; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Operation/FoldRight.php: -------------------------------------------------------------------------------- 1 | ): V): Closure(V): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param callable(V, T, TKey, iterable): V $callback 28 | * 29 | * @return Closure(V): Closure(iterable): Generator 30 | */ 31 | static fn (callable $callback): Closure => 32 | /** 33 | * @param V $initial 34 | * 35 | * @return Closure(iterable): Generator 36 | */ 37 | static function (mixed $initial = null) use ($callback): Closure { 38 | /** @var Closure(iterable): Generator $pipe */ 39 | $pipe = (new Pipe())()( 40 | (new ScanRight())()($callback)($initial), 41 | (new Head())() 42 | ); 43 | 44 | // Point free style. 45 | return $pipe; 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Operation/FoldRight1.php: -------------------------------------------------------------------------------- 1 | ): V): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param callable((T|V), T, TKey, iterable): V $callback 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static function (callable $callback): Closure { 32 | /** @var Closure(iterable):(Generator) $pipe */ 33 | $pipe = (new Pipe())()( 34 | (new ScanRight1())()($callback), 35 | (new Head())() 36 | ); 37 | 38 | // Point free style. 39 | return $pipe; 40 | }; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Operation/Forget.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param array $keys 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static fn (array $keys): Closure => (new Filter())()( 32 | /** 33 | * @param T $value 34 | * @param TKey $key 35 | */ 36 | static fn (mixed $value, mixed $key): bool => !in_array($key, $keys, true) 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Operation/Frequency.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | $reduceCallback = 24 | /** 25 | * @param array $storage 26 | * @param T $value 27 | * 28 | * @return array 29 | */ 30 | static function (array $storage, $value): array { 31 | $added = false; 32 | 33 | foreach ($storage as $key => $data) { 34 | if ($data[1] !== $value) { 35 | continue; 36 | } 37 | 38 | ++$storage[$key][0]; 39 | $added = true; 40 | 41 | break; 42 | } 43 | 44 | if (true !== $added) { 45 | $storage[] = [1, $value]; 46 | } 47 | 48 | return $storage; 49 | }; 50 | 51 | /** @var Closure(iterable): Generator $pipe */ 52 | $pipe = (new Pipe())()( 53 | (new Reduce())()($reduceCallback)([]), 54 | (new Flatten())()(1), 55 | (new Unpack())() 56 | ); 57 | 58 | // Point free style. 59 | return $pipe; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Operation/Group.php: -------------------------------------------------------------------------------- 1 | ): Generator> 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @param iterable $iterable 26 | * 27 | * @return Generator> 28 | */ 29 | static function (iterable $iterable): Generator { 30 | $last = []; 31 | 32 | foreach ($iterable as $current) { 33 | if ([] === $last) { 34 | $last = [$current]; 35 | 36 | continue; 37 | } 38 | 39 | if (current($last) === $current) { 40 | $last[] = $current; 41 | 42 | continue; 43 | } 44 | 45 | yield $last; 46 | 47 | $last = [$current]; 48 | } 49 | 50 | if ([] !== $last) { 51 | yield $last; 52 | } 53 | }; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Operation/Has.php: -------------------------------------------------------------------------------- 1 | ): T ...): Closure(iterable): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @param callable(T, TKey, iterable): T ...$callbacks 26 | * 27 | * @return Closure(iterable): Generator 28 | */ 29 | static fn (callable ...$callbacks): Closure => (new MatchOne())()(static fn (): bool => true)( 30 | ...array_map( 31 | static fn (callable $callback): callable => 32 | /** 33 | * @param T $value 34 | * @param TKey $key 35 | * @param iterable $iterable 36 | */ 37 | static fn (mixed $value, mixed $key, iterable $iterable): bool => $callback($value, $key, $iterable) === $value, 38 | $callbacks 39 | ) 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Operation/Head.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return (new Limit())()(1)(0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Operation/Implode.php: -------------------------------------------------------------------------------- 1 | ): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @return Closure(iterable): Generator 27 | */ 28 | static function (string $glue): Closure { 29 | /** @var Closure(iterable): Generator $pipe */ 30 | $pipe = (new Pipe())()( 31 | (new Intersperse())()($glue)(1)(0), 32 | (new Limit())()(-1)(1), 33 | (new Reduce())()( 34 | static fn (string $carry, string|Stringable $item): string => $carry .= (string) $item 35 | )('') 36 | ); 37 | 38 | // Point free style. 39 | return $pipe; 40 | }; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Operation/Init.php: -------------------------------------------------------------------------------- 1 | ): Generator 22 | * 23 | * @psalm-suppress InvalidArgument 24 | */ 25 | public function __invoke(): Closure 26 | { 27 | $buildCachingIterator = 28 | /** 29 | * @return CachingIteratorAggregate 30 | */ 31 | static fn (iterable $iterator): CachingIteratorAggregate => new CachingIteratorAggregate((new IterableIteratorAggregate($iterator))->getIterator()); 32 | 33 | /** @var Closure(iterable): Generator $takeWhile */ 34 | $takeWhile = (new Pipe())()( 35 | $buildCachingIterator, 36 | (new TakeWhile())()( 37 | /** 38 | * @param T $value 39 | * @param TKey $key 40 | * @param CachingIteratorAggregate $iterator 41 | */ 42 | static fn ($value, $key, CachingIteratorAggregate $iterator): bool => $iterator->hasNext() 43 | ) 44 | ); 45 | 46 | // Point free style. 47 | return $takeWhile; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Operation/Inits.php: -------------------------------------------------------------------------------- 1 | ): Generator> 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator> $inits */ 24 | $inits = (new Pipe())()( 25 | (new Pack())(), 26 | (new ScanLeft())()( 27 | /** 28 | * @param list $carry 29 | * @param array{0: TKey, 1: T} $value 30 | * 31 | * @return list 32 | */ 33 | static function (array $carry, array $value): array { 34 | $carry[] = $value; 35 | 36 | return $carry; 37 | } 38 | )([]), 39 | (new Normalize())() 40 | ); 41 | 42 | // Point free style. 43 | return $inits; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Operation/Intersect.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param array $values 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static fn (array $values): Closure => (new Filter())()( 32 | /** 33 | * @param T $value 34 | */ 35 | static fn (mixed $value): bool => in_array($value, $values, true) 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Operation/IntersectKeys.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param array $keys 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static fn (array $keys): Closure => (new Filter())()( 32 | /** 33 | * @param T $value 34 | * @param TKey $key 35 | */ 36 | static fn (mixed $value, mixed $key): bool => in_array($key, $keys, true) 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Operation/IsEmpty.php: -------------------------------------------------------------------------------- 1 | ): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return static fn (iterable $iterable): Generator => yield !(new IterableIteratorAggregate($iterable))->getIterator()->valid(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Operation/IsNotEmpty.php: -------------------------------------------------------------------------------- 1 | ): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return static fn (iterable $iterable): Generator => yield (new IterableIteratorAggregate($iterable))->getIterator()->valid(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Operation/Key.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @return Closure(iterable): Generator 26 | */ 27 | static function (int $index): Closure { 28 | /** @var Closure(iterable): Generator $pipe */ 29 | $pipe = (new Pipe())()( 30 | (new Limit())()(1)($index), 31 | (new Flip())() 32 | ); 33 | 34 | // Point free style. 35 | return $pipe; 36 | }; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Operation/Keys.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator $pipe */ 24 | $pipe = (new Pipe())()( 25 | (new Flip())(), 26 | (new Normalize())() 27 | ); 28 | 29 | // Point free style. 30 | return $pipe; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Operation/Last.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator $pipe */ 24 | $pipe = (new Pipe())()( 25 | (new Reverse())(), 26 | // We could use `Head` here, but I use `Limit` for minor perf boost. 27 | (new Limit())()(1)(0) 28 | ); 29 | 30 | // Point free style. 31 | return $pipe; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Operation/Limit.php: -------------------------------------------------------------------------------- 1 | ): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @return Closure(int): Closure(iterable): Generator 27 | */ 28 | static fn (int $count = -1): Closure => 29 | /** 30 | * @return Closure(iterable): Generator 31 | */ 32 | static fn (int $offset = 0): Closure => 33 | /** 34 | * @param iterable $iterable 35 | * 36 | * @return Generator 37 | */ 38 | static fn (iterable $iterable): Generator => yield from new LimitIterableAggregate($iterable, $offset, $count); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Operation/Lines.php: -------------------------------------------------------------------------------- 1 | ): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | /** @var Closure(iterable): Generator $pipe */ 26 | $pipe = (new Pipe())()( 27 | (new Explode())()([PHP_EOL, "\n", "\r\n"]), 28 | (new Map())()( 29 | /** 30 | * @param list $value 31 | */ 32 | static fn (array $value): string => implode('', $value) 33 | ) 34 | ); 35 | 36 | // Point free style. 37 | return $pipe; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Operation/Map.php: -------------------------------------------------------------------------------- 1 | ): mixed): Closure(iterable): Generator 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @param callable(T, TKey, iterable): V $callback 29 | */ 30 | static fn (callable $callback): Closure => 31 | /** 32 | * @param iterable $iterable 33 | * 34 | * @return Generator 35 | */ 36 | static fn (iterable $iterable): Generator => yield from new MapIterableAggregate($iterable, Closure::fromCallable($callback)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Operation/Max.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | $comparator = 24 | /** 25 | * @param T $carry 26 | * @param T $value 27 | * 28 | * @return T 29 | */ 30 | static fn (mixed $carry, mixed $value): mixed => max($value, $carry); 31 | 32 | return (new Compare())()($comparator); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Operation/Merge.php: -------------------------------------------------------------------------------- 1 | ...$sources): Closure(iterable): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param iterable ...$sources 27 | */ 28 | static fn (iterable ...$sources): Closure => 29 | /** 30 | * @param iterable $iterable 31 | * 32 | * @return Generator 33 | */ 34 | static fn (iterable $iterable): Generator => yield from new ConcatIterableAggregate([$iterable, ...array_values($sources)]); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Operation/Min.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | $comparator = 24 | /** 25 | * @param T $carry 26 | * @param T $value 27 | * 28 | * @return T 29 | */ 30 | static fn (mixed $carry, mixed $value): mixed => min($value, $carry); 31 | 32 | return (new Compare())()($comparator); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Operation/Normalize.php: -------------------------------------------------------------------------------- 1 | ): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param iterable $iterable 27 | * 28 | * @return Generator 29 | */ 30 | static fn (iterable $iterable): Generator => yield from new NormalizeIterableAggregate($iterable); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Operation/Nth.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @return Closure(int): Closure(iterable): Generator 26 | */ 27 | static fn (int $step): Closure => 28 | /** 29 | * @return Closure(iterable): Generator 30 | */ 31 | static function (int $offset) use ($step): Closure { 32 | /** @var Closure(iterable): Generator $pipe */ 33 | $pipe = (new Pipe())()( 34 | (new Pack())(), 35 | (new Filter())()( 36 | /** 37 | * @param array{0: TKey, 1: T} $value 38 | */ 39 | static fn (array $value, int $key): bool => (($key % $step) === $offset) 40 | ), 41 | (new Unpack())() 42 | ); 43 | 44 | // Point free style. 45 | return $pipe; 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Operation/Nullsy.php: -------------------------------------------------------------------------------- 1 | , 2: int, 3: bool, 4: string} 22 | */ 23 | public const VALUES = [null, [], 0, false, '']; 24 | 25 | /** 26 | * @return Closure(iterable): Generator 27 | */ 28 | public function __invoke(): Closure 29 | { 30 | return (new Every())()( 31 | /** 32 | * @param T $value 33 | */ 34 | static fn (int $index, mixed $value): bool => in_array((bool) $value, self::VALUES, true) 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Operation/Pack.php: -------------------------------------------------------------------------------- 1 | ): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param iterable $iterable 27 | * 28 | * @return Generator 29 | */ 30 | static fn (iterable $iterable): Generator => yield from new PackIterableAggregate($iterable); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Operation/Pad.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @return Closure(T): Closure(iterable): Generator 26 | */ 27 | static fn (int $size): Closure => 28 | /** 29 | * @param T $padValue 30 | * 31 | * @return Closure(iterable): Generator 32 | */ 33 | static fn (mixed $padValue): Closure => 34 | /** 35 | * @param iterable $iterable 36 | * 37 | * @return Generator 38 | */ 39 | static function (iterable $iterable) use ($size, $padValue): Generator { 40 | $y = 0; 41 | 42 | foreach ($iterable as $key => $value) { 43 | ++$y; 44 | 45 | yield $key => $value; 46 | } 47 | 48 | while ($y++ < $size) { 49 | yield $padValue; 50 | } 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Operation/Pair.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator $pipe */ 24 | $pipe = (new Pipe())()( 25 | (new Normalize())(), 26 | (new Chunk())()(2), 27 | (new Associate())()( 28 | /** 29 | * @param TKey $key 30 | * @param array{0: TKey, 1: T} $value 31 | * 32 | * @return TKey|null 33 | */ 34 | static fn (mixed $key, array $value): mixed => $value[0] ?? null 35 | )( 36 | /** 37 | * @param array{0: TKey, 1: T} $value 38 | * 39 | * @return T|null 40 | */ 41 | static fn (array $value): mixed => $value[1] ?? null 42 | ) 43 | ); 44 | 45 | // Point free style. 46 | return $pipe; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Operation/Partition.php: -------------------------------------------------------------------------------- 1 | ): bool ...): Closure(iterable): Generator> 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | /** 27 | * @param callable(T, TKey, iterable): bool ...$callbacks 28 | * 29 | * @return Closure(iterable): Generator> 30 | */ 31 | return static fn (callable ...$callbacks): Closure => 32 | /** 33 | * @param iterable $iterable 34 | * 35 | * @return Generator> 36 | */ 37 | static function (iterable $iterable) use ($callbacks): Generator { 38 | $iteratorAggregate = (new CachingIteratorAggregate((new IterableIteratorAggregate($iterable))->getIterator())); 39 | 40 | yield new ClosureIteratorAggregate((new Filter())()(...$callbacks), [$iteratorAggregate]); 41 | 42 | yield new ClosureIteratorAggregate((new Reject())()(...$callbacks), [$iteratorAggregate]); 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Operation/Pipe.php: -------------------------------------------------------------------------------- 1 | ): iterable ...): Closure(iterable): iterable 19 | */ 20 | public function __invoke(): Closure 21 | { 22 | return 23 | /** 24 | * @param callable(iterable): iterable ...$operations 25 | * 26 | * @return Closure(iterable): iterable 27 | */ 28 | static fn (callable ...$operations): Closure => array_reduce( 29 | $operations, 30 | /** 31 | * @param callable(iterable): iterable $f 32 | * @param callable(iterable): iterable $g 33 | * 34 | * @return Closure(iterable): iterable 35 | */ 36 | static fn (callable $f, callable $g): Closure => 37 | /** 38 | * @param iterable $iterable 39 | * 40 | * @return iterable 41 | */ 42 | static fn (iterable $iterable): iterable => $g($f($iterable)), 43 | static fn (iterable $iterable): iterable => $iterable 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Operation/Prepend.php: -------------------------------------------------------------------------------- 1 | ): Closure(iterable): iterable 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @param array $items 29 | * 30 | * @return Closure(iterable): iterable 31 | */ 32 | static fn (array $items): Closure => 33 | /** 34 | * @param iterable $iterable 35 | * 36 | * @return Generator 37 | */ 38 | static fn (iterable $iterable): Generator => yield from new ConcatIterableAggregate([$items, $iterable]); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Operation/RSample.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @return Closure(iterable): Generator 26 | */ 27 | static function (float $probability): Closure { 28 | $filter = (new Filter())()( 29 | static fn (): bool => (random_int(0, mt_getrandmax()) / mt_getrandmax()) < $probability 30 | ); 31 | 32 | // Point free style. 33 | return $filter; 34 | }; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Operation/Random.php: -------------------------------------------------------------------------------- 1 | ): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @return Closure(int): Closure(iterable): Generator 28 | */ 29 | static fn (int $seed): Closure => 30 | /** 31 | * @return Closure(iterable): Generator 32 | */ 33 | static fn (int $size): Closure => 34 | /** 35 | * @param iterable $iterable 36 | * 37 | * @return Generator 38 | */ 39 | static function (iterable $iterable) use ($seed, $size): Generator { 40 | // Point free style. 41 | yield from new LimitIterableAggregate(new RandomIterableAggregate($iterable, $seed), 0, $size); 42 | }; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Operation/Range.php: -------------------------------------------------------------------------------- 1 | 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @return Closure(int|float=): Closure(int|float=): Closure(): Generator 28 | */ 29 | static fn (float|int $start = 0.0): Closure => 30 | /** 31 | * @return Closure(int|float=): Closure(): Generator 32 | */ 33 | static fn (float|int $end = INF): Closure => 34 | /** 35 | * @return Closure(): Generator 36 | */ 37 | static fn (float|int $step = 1.0): Closure => 38 | /** 39 | * @return Generator 40 | */ 41 | static function () use ($start, $end, $step): Generator { 42 | for ($current = $start; $current < $end; $current += $step) { 43 | yield (($intCurrent = (int) $current) === $current) ? $intCurrent : $current; 44 | } 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Operation/Reduce.php: -------------------------------------------------------------------------------- 1 | ): mixed): Closure(mixed): Closure(iterable): Generator 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @param callable(V, T, TKey, iterable): V $callback 29 | * 30 | * @return Closure(V): Closure(iterable): Generator 31 | */ 32 | static fn (callable $callback): Closure => 33 | /** 34 | * @param V $initial 35 | * 36 | * @return Closure(iterable): Generator 37 | */ 38 | static fn (mixed $initial): Closure => 39 | /** 40 | * @param iterable $iterable 41 | * 42 | * @return Generator 43 | */ 44 | static fn (iterable $iterable): Generator => yield from new ReduceIterableAggregate($iterable, Closure::fromCallable($callback), $initial); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Operation/Reduction.php: -------------------------------------------------------------------------------- 1 | ): mixed): Closure(mixed): Closure(iterable): Generator 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @param callable(V, T, TKey, iterable): V $callback 29 | * 30 | * @return Closure(V): Closure(iterable): Generator 31 | */ 32 | static fn (callable $callback): Closure => 33 | /** 34 | * @param V $initial 35 | * 36 | * @return Closure(iterable): Generator 37 | */ 38 | static fn (mixed $initial): Closure => 39 | /** 40 | * @param iterable $iterable 41 | * 42 | * @return Generator 43 | */ 44 | static fn (iterable $iterable): Generator => yield from new ReductionIterableAggregate($iterable, Closure::fromCallable($callback), $initial); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Operation/Reverse.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | $callback = 24 | /** 25 | * @param T $value 26 | * @param TKey $key 27 | * @param list $carry 28 | * 29 | * @return list 30 | */ 31 | static fn (array $carry, mixed $value, mixed $key): array => [[$key, $value], ...$carry]; 32 | 33 | /** @var Closure(iterable): Generator $pipe */ 34 | $pipe = (new Pipe())()( 35 | (new Reduce())()($callback)([]), 36 | (new Unwrap())(), 37 | (new Unpack())() 38 | ); 39 | 40 | // Point free style. 41 | return $pipe; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Operation/ScanLeft.php: -------------------------------------------------------------------------------- 1 | ): mixed): Closure(mixed): Closure(iterable): Generator 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @param callable(V, T, TKey, iterable): V $callback 29 | * 30 | * @return Closure(V): Closure(iterable): Generator 31 | */ 32 | static fn (callable $callback): Closure => 33 | /** 34 | * @param V $initial 35 | * 36 | * @return Closure(iterable): Generator 37 | */ 38 | static fn (mixed $initial): Closure => 39 | /** 40 | * @param iterable $iterable 41 | * 42 | * @return Generator 43 | */ 44 | static fn (iterable $iterable): Generator => yield from new ReductionIterableAggregate($iterable, Closure::fromCallable($callback), $initial); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Operation/ScanRight.php: -------------------------------------------------------------------------------- 1 | ): mixed): Closure(mixed): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param callable(V, T, TKey, iterable): V $callback 28 | * 29 | * @return Closure(V): Closure(iterable): Generator 30 | */ 31 | static fn (callable $callback): Closure => 32 | /** 33 | * @param V $initial 34 | * 35 | * @return Closure(iterable): Generator 36 | */ 37 | static function (mixed $initial) use ($callback): Closure { 38 | /** @var Closure(iterable): Generator $pipe */ 39 | $pipe = (new Pipe())()( 40 | (new Reverse())(), 41 | (new ScanLeft())()($callback)($initial), 42 | (new Reverse())() 43 | ); 44 | 45 | // Point free style. 46 | return $pipe; 47 | }; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Operation/ScanRight1.php: -------------------------------------------------------------------------------- 1 | ): (T|V)): Closure(iterable): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param callable((T|V), T, TKey, iterable): (T|V) $callback 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static function (callable $callback): Closure { 32 | /** @var Closure(iterable): Generator $pipe */ 33 | $pipe = (new Pipe())()( 34 | (new Reverse())(), 35 | (new ScanLeft1())()($callback), 36 | (new Reverse())() 37 | ); 38 | 39 | // Point free style. 40 | return $pipe; 41 | }; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Operation/Shuffle.php: -------------------------------------------------------------------------------- 1 | ): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @return Closure(iterable): Generator 27 | */ 28 | static fn (int $seed): Closure => 29 | /** 30 | * @param iterable $iterable 31 | * 32 | * @return Generator 33 | */ 34 | static fn (iterable $iterable): Generator => yield from new RandomIterableAggregate($iterable, $seed); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Operation/Slice.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @return Closure(int=): Closure(iterable): Generator 26 | */ 27 | static fn (int $offset): Closure => 28 | /** 29 | * @return Closure(iterable): Generator 30 | */ 31 | static function (int $length = -1) use ($offset): Closure { 32 | /** @var Closure(iterable): Generator $skip */ 33 | $skip = (new Limit())()(-1)($offset); 34 | 35 | if (-1 === $length) { 36 | return $skip; 37 | } 38 | 39 | /** @var Closure(iterable): Generator $pipe */ 40 | $pipe = (new Pipe())()( 41 | $skip, 42 | (new Limit())()($length)(0) 43 | ); 44 | 45 | // Point free style. 46 | return $pipe; 47 | }; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Operation/Span.php: -------------------------------------------------------------------------------- 1 | ): bool ...): Closure(iterable): Generator> 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | /** 27 | * @param callable(T, TKey, iterable): bool ...$callbacks 28 | * 29 | * @return Closure(iterable): Generator> 30 | */ 31 | return static fn (callable ...$callbacks): Closure => 32 | /** 33 | * @param iterable $iterable 34 | * 35 | * @return Generator> 36 | */ 37 | static function (iterable $iterable) use ($callbacks): Generator { 38 | $iteratorAggregate = new CachingIteratorAggregate((new IterableIteratorAggregate($iterable))->getIterator()); 39 | 40 | yield new ClosureIteratorAggregate((new TakeWhile())()(...$callbacks), [$iteratorAggregate]); 41 | 42 | yield new ClosureIteratorAggregate((new DropWhile())()(...$callbacks), [$iteratorAggregate]); 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Operation/Strict.php: -------------------------------------------------------------------------------- 1 | ): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return 26 | /** 27 | * @param null|callable(mixed): string $callback 28 | * 29 | * @return Closure(iterable): Generator 30 | */ 31 | static fn (?callable $callback = null): Closure => 32 | /** 33 | * @return Generator 34 | */ 35 | static fn (iterable $iterator): Generator => yield from new TypedIterableAggregate((new IterableIteratorAggregate($iterator))->getIterator(), $callback); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Operation/Tail.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return (new Limit())()(-1)(1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Operation/Tails.php: -------------------------------------------------------------------------------- 1 | ): Generator> 23 | */ 24 | public function __invoke(): Closure 25 | { 26 | return 27 | /** 28 | * @param iterable $iterable 29 | * 30 | * @return Generator> 31 | */ 32 | static function (iterable $iterable): Generator { 33 | $initial = iterator_to_array( 34 | (new IterableIteratorAggregate($iterable))->getIterator() 35 | ); 36 | 37 | $reduction = 38 | /** 39 | * @param list $stack 40 | * 41 | * @return list 42 | */ 43 | static fn (array $stack): array => array_slice($stack, 1); 44 | 45 | /** @var Closure(iterable): Generator> $pipe */ 46 | $pipe = (new Pipe())()( 47 | (new Reduction())()($reduction)($initial), 48 | (new Normalize())(), 49 | ); 50 | 51 | yield from $pipe($iterable); 52 | }; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Operation/TakeWhile.php: -------------------------------------------------------------------------------- 1 | ): bool ...): Closure(iterable): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param callable(T, TKey, iterable): bool ...$callbacks 27 | * 28 | * @return Closure(iterable): Generator 29 | */ 30 | static fn (callable ...$callbacks): Closure => 31 | /** 32 | * @param iterable $iterable 33 | * 34 | * @return Generator 35 | */ 36 | static function (iterable $iterable) use ($callbacks): Generator { 37 | $callback = CallbacksArrayReducer::or()($callbacks); 38 | 39 | foreach ($iterable as $key => $current) { 40 | if (false === $callback($current, $key, $iterable)) { 41 | break; 42 | } 43 | 44 | yield $key => $current; 45 | } 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Operation/Tap.php: -------------------------------------------------------------------------------- 1 | ):void ...): Closure(iterable): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @param callable(T, TKey, iterable): void ...$callbacks 26 | * 27 | * @return Closure(iterable): Generator 28 | */ 29 | static fn (callable ...$callbacks): Closure => /** 30 | * @param iterable $iterable 31 | * 32 | * @return Generator 33 | */ 34 | static function (iterable $iterable) use ($callbacks): Generator { 35 | foreach ($iterable as $key => $value) { 36 | foreach ($callbacks as $callback) { 37 | $callback($value, $key, $iterable); 38 | } 39 | 40 | yield $key => $value; 41 | } 42 | }; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Operation/Times.php: -------------------------------------------------------------------------------- 1 | ): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @return Closure(null|callable(int): (int|T)): Closure(): Generator 27 | */ 28 | static fn (int $number = 0): Closure => 29 | /** 30 | * @return Closure(): Generator 31 | */ 32 | static fn (?callable $callback = null): Closure => 33 | /** 34 | * @return Generator 35 | */ 36 | static function () use ($number, $callback): Generator { 37 | if (1 > $number) { 38 | return; 39 | } 40 | 41 | $callback ??= static fn (int $value): int => $value; 42 | 43 | for ($current = 1; $current <= $number; ++$current) { 44 | yield $callback($current); 45 | } 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Operation/Transpose.php: -------------------------------------------------------------------------------- 1 | ): Generator> 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | $callbackForKeys = 26 | /** 27 | * @param non-empty-array $key 28 | * 29 | * @return TKey 30 | */ 31 | static fn (array $key): mixed => reset($key); 32 | 33 | $callbackForValues = 34 | /** 35 | * @param array $value 36 | * 37 | * @return array 38 | */ 39 | static fn (array $value): array => $value; 40 | 41 | /** @var Closure(iterable): Generator> $pipe */ 42 | $pipe = (new Pipe())()( 43 | static fn (iterable $iterables): MultipleIterableAggregate => new MultipleIterableAggregate($iterables, MultipleIterator::MIT_NEED_ANY), 44 | (new Associate())()($callbackForKeys)($callbackForValues) 45 | ); 46 | 47 | // Point free style. 48 | return $pipe; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/Operation/Truthy.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return (new Every())()( 24 | /** 25 | * @param T $value 26 | */ 27 | static fn (int $index, mixed $value): bool => (bool) $value 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Operation/Unfold.php: -------------------------------------------------------------------------------- 1 | ): Closure(callable(T...): iterable): Closure(): Generator> 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @param iterable $parameters 26 | * 27 | * @return Closure(callable(T...): iterable): Closure(): Generator> 28 | */ 29 | static fn (iterable $parameters): Closure => 30 | /** 31 | * @param callable(T...): iterable $callback 32 | * 33 | * @return Closure(): Generator> 34 | */ 35 | static fn (callable $callback): Closure => 36 | /** 37 | * @return Generator> 38 | */ 39 | static function () use ($parameters, $callback): Generator { 40 | while (true) { 41 | $parameters = $callback(...$parameters); 42 | 43 | yield $parameters; 44 | } 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Operation/Unlines.php: -------------------------------------------------------------------------------- 1 | ): Generator 22 | */ 23 | public function __invoke(): Closure 24 | { 25 | return (new Implode())()(PHP_EOL); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Operation/Unpack.php: -------------------------------------------------------------------------------- 1 | ): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param iterable $iterable 27 | */ 28 | static fn (iterable $iterable): Generator => yield from new UnpackIterableAggregate($iterable); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Operation/Unpair.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return 24 | /** 25 | * @param iterable $iterable 26 | * 27 | * @return Generator 28 | */ 29 | static function (iterable $iterable): Generator { 30 | foreach ($iterable as $key => $value) { 31 | yield $key; 32 | 33 | yield $value; 34 | } 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Operation/Until.php: -------------------------------------------------------------------------------- 1 | ): bool ...): Closure(iterable): Generator 21 | */ 22 | public function __invoke(): Closure 23 | { 24 | return 25 | /** 26 | * @param callable(T, TKey, iterable): bool ...$callbacks 27 | * 28 | * @return Closure(iterable): Generator 29 | */ 30 | static fn (callable ...$callbacks): Closure => 31 | /** 32 | * @param iterable $iterable 33 | * 34 | * @return Generator 35 | */ 36 | static function (iterable $iterable) use ($callbacks): Generator { 37 | $callback = CallbacksArrayReducer::or()($callbacks); 38 | 39 | foreach ($iterable as $key => $current) { 40 | yield $key => $current; 41 | 42 | if ($callback($current, $key, $iterable)) { 43 | break; 44 | } 45 | } 46 | }; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Operation/Unwindow.php: -------------------------------------------------------------------------------- 1 | >): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable>): Generator $pipe */ 24 | $pipe = (new Pipe())()( 25 | (new Map())()( 26 | /** 27 | * @param list $iterable 28 | * 29 | * @return Generator 30 | */ 31 | static fn (iterable $iterable): Generator => (new Last())()($iterable) 32 | ), 33 | (new Map())()( 34 | /** 35 | * @param Generator $iterable 36 | * 37 | * @return T|null 38 | */ 39 | static fn (Generator $iterable): mixed => $iterable->current() 40 | ), 41 | ); 42 | 43 | // Point free style. 44 | return $pipe; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Operation/Unwords.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | return (new Implode())()(' '); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Operation/Unwrap.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator $flatten */ 24 | $flatten = (new Flatten())()(1); 25 | 26 | // Point free style. 27 | return $flatten; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Operation/Unzip.php: -------------------------------------------------------------------------------- 1 | >): Generator> 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | $reduceCallback = 24 | /** 25 | * @param array> $carry 26 | * @param iterable $value 27 | * 28 | * @return array> 29 | */ 30 | static function (array $carry, iterable $value): array { 31 | $index = 0; 32 | 33 | foreach ($value as $carry[$index++][]); 34 | 35 | return $carry; 36 | }; 37 | 38 | /** @var Closure(iterable>): Generator> $pipe */ 39 | $pipe = (new Pipe())()( 40 | (new Reduce())()($reduceCallback)([]), 41 | (new Flatten())()(1) 42 | ); 43 | 44 | // Point free style. 45 | return $pipe; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Operation/Window.php: -------------------------------------------------------------------------------- 1 | ): Generator> 24 | */ 25 | public function __invoke(): Closure 26 | { 27 | return 28 | /** 29 | * @return Closure(iterable): Generator> 30 | */ 31 | static fn (int $size): Closure => 32 | /** 33 | * @param iterable $iterable 34 | * 35 | * @return Generator> 36 | */ 37 | static fn (iterable $iterable): Generator => yield from new LimitIterableAggregate(new ReductionIterableAggregate( 38 | $iterable, 39 | /** 40 | * @param list $stack 41 | * @param T $current 42 | * 43 | * @return list 44 | */ 45 | static fn (array $stack, mixed $current): array => array_slice([...$stack, $current], ++$size * -1), 46 | [] 47 | ), 1); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Operation/Words.php: -------------------------------------------------------------------------------- 1 | ): Generator 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator $pipe */ 24 | $pipe = (new Pipe())()( 25 | (new Explode())()(["\t", "\n", ' ']), 26 | (new Map())()( 27 | /** 28 | * @param list $value 29 | */ 30 | static fn (array $value): string => implode('', $value) 31 | ), 32 | (new Compact())()([]) 33 | ); 34 | 35 | // Point free style. 36 | return $pipe; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Operation/Wrap.php: -------------------------------------------------------------------------------- 1 | ): Generator> 20 | */ 21 | public function __invoke(): Closure 22 | { 23 | /** @var Closure(iterable): Generator> $pipe */ 24 | $pipe = (new Pipe())()( 25 | (new Map())()( 26 | /** 27 | * @param T $value 28 | * @param TKey $key 29 | * 30 | * @return array 31 | */ 32 | static fn (mixed $value, mixed $key): array => [$key => $value] 33 | ), 34 | (new Normalize())() 35 | ); 36 | 37 | // Point free style. 38 | return $pipe; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Operation/Zip.php: -------------------------------------------------------------------------------- 1 | ...): Closure(iterable): Generator, list> 25 | */ 26 | public function __invoke(): Closure 27 | { 28 | return 29 | /** 30 | * @param iterable ...$iterables 31 | * 32 | * @return Closure(iterable): Generator, list> 33 | */ 34 | static fn (iterable ...$iterables): Closure => 35 | /** 36 | * @param iterable $iterable 37 | * 38 | * @return Generator, list> 39 | */ 40 | static fn (iterable $iterable): Generator => yield from new MultipleIterableAggregate([$iterable, ...array_values($iterables)], MultipleIterator::MIT_NEED_ANY); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Utils/CallbacksArrayReducer.php: -------------------------------------------------------------------------------- 1 | ): Closure(mixed...): bool 18 | */ 19 | public static function or(): Closure 20 | { 21 | return 22 | /** 23 | * @param array $callbacks 24 | * 25 | * @return Closure(mixed...): bool 26 | */ 27 | static fn (array $callbacks): Closure => static fn (mixed ...$parameters): bool => array_reduce( 28 | $callbacks, 29 | /** 30 | * @param callable(mixed...): bool $callable 31 | */ 32 | static fn (bool $carry, callable $callable): bool => $carry || $callable(...$parameters), 33 | false 34 | ); 35 | } 36 | } 37 | --------------------------------------------------------------------------------