IDLES PHP functional library
theme github

PHP FUNCTIONAL UTILITY LIBRARY

What is it?

Idles is a PHP functional utility library, a port of Javascript Lodash/Fp and Ramda libraries to PHP language. It comprises a set of side-effect free, immutable and automatically curried functions that support lazy evaluation. The iterable collection parameter is usually supplied last to make currying convenient. Such design makes it easy to create functional pipelines with a possibility of delayed evaluation.

Requirements

PHP: ^7.4

Installation

composer require miroshnikov/idles

Usage

All methods are in Idles\ namespace, immutable, pure and auto-curried.

Binary safe, mb_* functions are used for string methods.

The comparison everywhere by default is a weak equality check (==).

Usage example:

use function Idles\{pipe, map, divide, ary, partial, curryN, filter};
use const Idles\_;
pipe(
    map(divide(_, 2)),
    map(ary(1, partial(\round(...), [_, 0]))),
    map(curryN(1, \intval(...))),
    filter(fn ($n) => $n % 2)
)([2,3,4,8]);

Lazy evaluation

Most of the functions take any kind of iterable as a collection parameter and become lazy when given an Iterator or Generator as an input. When piped intermediate lazy operations are applied to every element of the iterator one after the other without collection all elements in memory array. Lazy pipelines operate on a "pull," rather than a "push" basis.

Although when given an array such method will NOT be lazy and return a modified array like a build-in PHP array_... function. The rule is: you will get back the same kind of iterable that you passed in as an argument.

collect function may be used to turn an iterable of any kind into an array.

icon marks lazy methods.

use function Idles\{pipe, map, filter, collect};

$generator = (function () {
    $fp = \fopen('/huge/file/with/numbers', 'r');
    while (($s = \fgets($fp)) !== false) {
        yield $s;
    }
})();

$iterator = pipe(
    map(fn ($v) => \intval(\trim($v), 10)),
    filter(fn ($v) => $v % 2 == 0),
    map(fn ($v) => "[$v]")
    // ...
)($generator);
// nothing has happened so far, no data has been requested

// now you can iterate over elements of $iterator with foreach
// or convert it into an array in memory by iterator_to_array or collect
$array = collect($iterator);

Array vs Record

The Idles library makes a distinction between arrays and records.

Array has only numerical sequential indexes. This is what the Array is in JavaScript and many other languages.

Record may have both numerical and string keys. AKA hash, map, object, hash table, or associative array in other languages. This is what the Object is in JavaScript.

icon marks methods that do not retain string keys and return indexed iterables.

filter(fn ($v) => $v == 'a' || $v == 'C')(['a', 'b', 'c' => 'C']); // ['a', 'C']

Placeholder

Idles\_ is a special placeholder used to specify "gaps" within curried or partially applied functions.

use function Idles\{curryN, partial};
use const Idles\_;

$greet = curryN(3, \str_replace(...))('{name}', _, 'Hello, {name}!');
// or
$greet = partial(\str_replace(...), ['{name}', _, 'Hello, {name}!']);
$greet('Alice'); // Hello, Alice!

Array

concat

concat(?iterable $array, $value): iterable
concatAll(array $values): iterable

Concatinates $array with additional iterables/values

Returns

Numerically indexed concatenated iterable

Example

concat(['a','b'], 'C');  // ['a', 'b', 'C']

See also

drop

drop(int $n, ?iterable $collection): iterable

Skips the first $n elemens and returns the rest of the iterable

Example

drop(1, [1, 2, 3]); // [2, 3]

See also

dropRight

dropRight(int $n, ?iterable $collection): iterable

Skips the last $n elements

Example

dropRight(2, [1, 2, 3]);  // [1]

Alias

  • dropLast

See also

findIndex

findIndex(callable $predicate, ?iterable $collection): int
findIndexFrom(callable $predicate, int $fromIndex, ?iterable $collection): int

Like find but returns the index of the first element predicate returns truthy for, -1 if not found

Arguments

$predicate
($value, $index, $collection): bool

Example

findIndex(['b', 'a', 'b', 'c'], fn ($v) => $v == 'b', 1); // 2
findIndexFrom(fn ($v) => $v == 'b', -2, ['a','b','a','b','c']) // 3 

See also

findLastIndex

findLastIndex(callable $predicate, ?iterable $collection): int
findLastIndexFrom(callable $predicate, int $fromIndex, ?iterable $collection): int

Like find but returns the index of the last element predicate returns truthy for, -1 if not found

Arguments

$predicate
($value, $index, $collection): bool

Example

findLastIndexFrom(fn ($v) => $v == 'b', 2, ['a', 'b', 'a', 'b']); // 1

See also

flatten

flatten(?iterable $collection): iterable

Flattens iterable a single level deep.

Example

flatten(['a' => 'A', ['b' => 'B'], 'c' => 'C']);  // ['A', 'B', 'C']

Alias

  • unnest

See also

flattenDeep

flattenDeep(?iterable $collection): iterable

Recursively flattens iterable.

Example

flattenDeep([1, [2, [3, [4]], 5]]);  // [1, 2, 3, 4, 5]

See also

flattenDepth

flattenDepth(int $depth, ?iterable $collection): iterable

Recursively flatten array up to depth times.

Example

flattenDepth(2, [1, [2, [3, [4]], 5]]);  // [1, 2, 3, [4], 5]

See also

fromPairs

fromPairs(?iterable $collection): array

Creates a new record from a list key-value pairs. The inverse of toPairs.

Example

fromPairs([['a', 1], ['b', 2], ['c', 3]]); // ['a' => 1, 'b' => 2, 'c' => 3]

See also

indexOf

indexOf($value, ?iterable $collection): int
indexOfFrom($value, int $fromIndex, ?iterable $collection): int

Returns the index of the first occurrence of $value in $collection, else -1.

Example

indexOf(2, [1, 2, 1, 2]); // 1

See also

intersection

intersection(?iterable $record1, ?iterable $record2): array

Returns unique values that are included in both records

Example

intersection(['a', 'a', 'b'], ['c', 'a', 'a']); // ['a']

See also

intersectionBy

intersectionBy(callable $iteratee, ?iterable $record1, ?iterable $record2): array

Like intersection but invokes $iteratee for each element before comparison.

Arguments

$iteratee
($value): mixed

Example

intersectionBy('\floor', [2.1, 1.2], [2.3, 3.4]); // [2.1]

See also

intersectionWith

intersectionWith(callable $comparator, ?iterable $record1, ?iterable $record2): array

Like intersection but invokes $comparator to compare elements.

Arguments

$comparator
($a, $b): int

Example

intersectionWith(fn ($a, $b) => $a <=> $b, ['a', 'a', 'b'], ['c', 'a', 'a']); // ['a']

See also

join

join(string $separator, ?iterable $collection): string

Joins iterable elements separated by $separator

Example

join('~', ['a', 'b', 'c']); // 'a~b~c'

See also

last

last(?iterable $collecton)

Gets the last element of iterable

Example

last([1, 2, 3]);  // 3

See also

nth

nth(int $offset, ?iterable $collection)

Returns the $offset element. If $offset is negative the element at index length + $offset is returned.

Example

$list = ['foo', 'bar', 'baz', 'quux'];
nth(1, $list); // 'bar'
nth(-1, $list); // 'quux'
nth(99, $list); // null

See also

remove

remove(int $start, int $count, ?iterable $iterable): array

Removes items from $iterable starting at $start and containing $count elements.

Example

remove(2, 3, [1,2,3,4,5,6,7,8]); // [1,2,6,7,8]

See also

slice

slice(int $start, int ?$end, ?iterable $collection): iterable

Retruns a slice of $iterable from $start up to, but not including, $end.

Example

$a = ['a','b','c','d','e'];
slice(1, 3, $a2); // ['b','c']
slice(1, -2, $a2); // ['b','c']
slice(-4, -2, $a2); // ['b','c']

See also

take

take(int $n, ?iterable $collection): iterable

Takes n first elements from iterable

Example

take(2, [1, 2, 3]);  // [1, 2]

See also

takeRight

takeRight(int $n, ?iterable $collection): array

Returns a slice of iterable with n elements taken from the end.

Example

takeRight(2, [1, 2, 3]);  // [2, 3]

See also

uniq

uniq(?iterable $collection): array

Removes duplicates using ===

Example

uniq([1, 1, 2, '1']); // [1, 2, '1']

See also

uniqueBy

uniqBy(callable $iteratee, ?iterable $collection): array

Like uniq but apply $iteratee fist

Arguments

$iteratee
($value): mixed

Example

uniqBy(\abs(...))([-1, -5, 2, 10, 1, 2]); // [-1, -5, 2, 10]

See also

uniqWith

uniqWith(callable $predicate, ?iterable $collection): array

Like uniq but uses $predicate to compare elements

Arguments

$predicate
($a, $b): bool

Example

uniqWith(fn ($a, $b) => $a == $b)([1, '1', 2, 1]); // [1, 2]

See also

without

without(array $values, ?iterable $collection): iterable

Returns $iterable without $values

Example

without([1, 2], [2, 1, 2, 3]);  // [3]

See also

zip

zip(iterable $a, iterable $b): iterable
zipAll(array $iterables): iterable

Creates an iterable of grouped elements, the first of which contains the first elements of the given iterables, the second of which contains the second elements, and so on.

Example

$a =  ['a', 'b' ];
$aa = ['AA','BB'];
zip($a, $aa);  // [ ['a', 'AA'], ['b', 'BB'] ]

See also

zipWith

zipWith(callable $iteratee, iterable $a, iterable $b): iterable

Like zip except that it accepts $iteratee to specify how grouped values should be combined.

Example

$a =  ['a', 'b' ];
$aa = ['AA','BB'];
zipWith(fn ($a,$b) => $a.'='.$b, $a, $aa);  // ["a=AA", "b=BB"]

See also

Collection

all

all(?callable $predicate, ?iterable $collection): bool

Checks if $predicate returns truthy for all elements of $collection. Stop once it returns falsey

Arguments

$predicate
($value): bool

Example

every('\is_numeric')([1,2,3]); // true

$users = [
    [ 'user' => 'barney', 'age' => 36, 'active' => true ],
    [ 'user' => 'fred',   'age' => 40, 'active' => true ]
];
all(property('active'))($users); // true

Alias

  • every

any

any(callable $predicate, ?iterable $collection): bool

Checks if $predicate returns truthy for any element of $collection. Stops on first found.

Arguments

$predicate
($value, $key, $collection): bool

Example

$users = [
    [ 'user' => 'barney', 'active' => false ],
    [ 'user' => 'fred',   'active' => true ]
];
any(fn ($r) => $r['active'] == true, $users); // true

Alias

  • some

See also

each

each(callable $iteratee, ?iterable $collection): iterable

Iterates over elements of $collection. Iteratee may exit iteration early by returning false.

Arguments

$iteratee
($value, $key, $collection): ?bool

Example

each(fn ($v) => print_r($v), [1,2,3]);

See also

filter

filter(callable $predicate, ?iterable $collection): iterable

Returns elements $predicate returns truthy for.

Arguments

$predicate
($value, $key, $collection): bool

Example

filter('is_numeric', ['a', 'b', 13]); // [13]

See also

find

find(?callable $predicate, ?iterable $collection)
findFrom(?callable $predicate, int $fromIndex, ?iterable $collection)

Returns the first element $predicate returns truthy for.

Arguments

$predicate
($value): bool

See also

flatMap

flatMap(callable $iteratee, ?iterable $collection): iterable

Maps then flatten

Arguments

$iteratee
($value, $key, $collection): mixed

Example

flatMap(fn ($n) => [$n, $n], [1,2]); // [1, 1, 2, 2]

Alias

  • chain

See also

flatMapDeep

flatMapDeep(callable $iteratee, ?iterable $collection): iterable

Like flatMap but recursively flattens the results.

Arguments

$iteratee
($value, $key, $collection): mixed

Example

flatMapDeep(fn ($n) => [[[$n, $n]]], [1, 2]); // [1, 1, 2, 2]

See also

flatMapDepth

flatMapDepth(callable $iteratee, int $depth, ?iterable $collection): iterable

Like flatMap but flattens the mapped results up to $depth times

Arguments

$iteratee
($value, $key, $collection): mixed

Example

flatMapDepth(fn ($n) => [[[$n, $n]]], 2, [1, 2]); // [[1, 1], [2, 2]]

See also

groupBy

groupBy(callable $iteratee, ?iterable $collection): array

Creates an array composed of keys generated from running each value through $iteratee.

Arguments

$iteratee
($value): mixed

Example

groupBy('strlen')(['one', 'two', 'three']); // [ '3' => ['one', 'two'], '5' => ['three'] ]

See also

includes

includes($value, ?iterable $collection): bool
includesFrom($value, int $fromIndex, ?iterable $collection): bool

Checks if $value is in $collection.

Example

includes(1, ['a' => 1, 'b' => 2]); // true

Alias

  • contains

See also

indexBy

indexBy(callable $iteratee, ?iterable $collection): iterable

Creates a record composed of keys generated from the results of running each element of $collection through $iteratee.

Arguments

$iteratee
($value): string|int

Example

$a = [ [ 'code' => 97 ],  [ 'code' => 100 ] ];
indexBy(fn ($r) => \chr($r['code']), $a); // ['a' => [ 'code' => 97 ], 'd' => [ 'code' => 100 ]],

Alias

  • keyBy

See also

map

map(callable $iteratee, ?iterable $collection)

Run each element in $collection through $iteratee.

Arguments

$iteratee
($value, $key, $collection): mixed

Example

map(fn ($n) => $n * $n, [4, 8]); // [16, 64]

Alias

  • mapValues

See also

orderBy

orderBy(array $iteratees, array $orders, ?iterable $collection)

Like sortBy but allows specifying the sort orders

Arguments

$iteratees
[(mixed $value): mixed]
$orders
['asc'|'desc']

Example

$users = [
    [ 'user' => 'fred',   'age' => 48 ],
    [ 'user' => 'barney', 'age' => 34 ],
    [ 'user' => 'fred',   'age' => 40 ],
    [ 'user' => 'barney', 'age' => 36 ]
];
orderBy([property('user'), property('age')], ['asc', 'desc'], $users);
/*
[
    [ 'user' => 'barney', 'age' => 36 ],
    [ 'user' => 'barney', 'age' => 34 ],
    [ 'user' => 'fred',   'age' => 48 ],
    [ 'user' => 'fred',   'age' => 40 ]
]
*/

See also

partition

partition(callable $predicate, ?iterable $collection): array

Split $collection into two groups, the first of which contains elements $predicate returns truthy for, the second of which contains elements $predicate returns falsey for.

Arguments

$predicate
(mixed $value): bool

Example

partition(
    fn ($v) => stripos($v, 'A') !== false, 
    ['a' => 'AA', 'b' => 'BB', 'c' => 'AAA']
); 
// [['a' => 'AA', 'c' => 'AAA'], ['b' => 'BB']]

See also

reduce

reduce(callable $iteratee, $accumulator, ?iterable $collection)

Reduces $collection to a value which is the accumulated result of running each element in collection through $iteratee

Arguments

$iteratee
($accumulator, $value, $key, $collection): mixed

Example

reduce(ary(2, subtract(...)), 0, [1, 2, 3, 4]); // -10

See also

resolve

resolve(array $resolvers, array $record): array

Adds new properties to $record using $resolvers.

Arguments

$resolvers
[string => callable]

Example

$users = [
    [ 'name' => 'Steve', 'surname' => 'Jobs'  ],
    [ 'name' => 'Bill',  'surname' => 'Gates' ]
];
map(
    resolve([
        'initials' => fn ($r) => $r['name'][0].$r['surname'][0]
    ]),
    $users
);
/*
[
    [ 'name' => 'Steve', 'surname' => 'Jobs',  'initials' => 'SJ' ],
    [ 'name' => 'Bill',  'surname' => 'Gates', 'initials' => 'BG' ]
]
*/

See also

sortBy

sortBy(array $iteratees, ?iterable $collection): array

Sorts $collection in ascending order according to $iteratees.

Arguments

$iteratees
[(mixed $value): mixed]

Example

$users = [
    [ 'user' => 'fred',   'age' => 48 ],
    [ 'user' => 'barney', 'age' => 36 ],
    [ 'user' => 'fred',   'age' => 40 ],
    [ 'user' => 'barney', 'age' => 34 ]
];
sortBy([property('user'), property('age')], $users);
/*
[
    [ 'user' => 'barney', 'age' => 34 ],
    [ 'user' => 'barney', 'age' => 36 ],
    [ 'user' => 'fred',   'age' => 40 ],
    [ 'user' => 'fred',   'age' => 48 ]
]
*/

See also

values

values(?iterable $collection): iterable

Returns an indexed iterable of values in $collection.

Example

values(['a' => 'AA', 'b' => 'BB']); // ['AA', 'BB']

See also

Function

always

always($value)

Returns a function that always returns the given value.

Alias

  • constant

applyTo

applyTo($value, callable $interceptor)

Returns $interceptor($value).

Example

$n13 = applyTo(13);
$n13(add(100)); // 113

Alias

  • thru

ary

ary(int $n, callable $fn): callable

Creates a function that invokes $fn, with up to $n arguments, ignoring any additional arguments.

Example

map(ary(1, '\intval'), ['6', '8', '10']); // [6, 8, 10]

Alias

  • nAry

See also

attempt

attempt(callable $fn)

Calls $fn, returning either the result or the caught exception.

Example

attempt(fn () => 'A'); // A
attempt(fn () => throw new \Exception('Error')); // Exception('Error')

See also

compose

compose(callable ...$funcs): callable
flowRight(array $funcs): callable

Like pipe but invokes the functions from right to left.

Example

compose('\strtoupper', fn ($s) => 'hello '.$s, '\trim')(' fred '); // 'HELLO FRED'

See also

curry

curry(callable $f): callable
curryN(int $arity, callable $f): callable

\Idles\_ const may be used as a placeholder.

Example

use const \Idles\_;

$abc = fn ($a, $b, $c = 'c') => $a.$b.$c;
curry($abc)('a')('b')('c'); // 'abc'
curryN(2, $abc)('a')('b'); // 'abc'
curry($abc)(_, 'b')(_, 'c')('a'); // 'abc'

See also

curryRight

curryRight(callable $f): callable
curryRightN(int $arity, callable $f): callable

Like curry but arguments are prepended.

Example

use const \Idles\_;

$abc = fn ($a, $b, $c = 'c') => $a.$b.$c;
curryRight($abc)('c')('b')('a'); // 'abc'
curryRight($abc)('b','c')('a'); // 'abc'
curryRightN(2, $abc)('b')('a'); // 'abc'

See also

flip

flip(callable $fn): callable

Returns a new curried function with the first two arguments reversed

Example

flip(fn ($a, $b, $c, $d) => [$a, $b, $c, $d])(1, 2)(3, 4); // [2, 1, 3, 4]

See also

juxt

juxt(array $funcs): callable

applies a list of functions to a list of values.

Example

juxt([\max(...), \min(...)])(1,2,3,4); // [4,1]

$isOdd = fn ($n) => $n % 2;
juxt([filter($isOdd), remove($isOdd)])([1,2,3,4,5,6,7,8,9]);
// [[1,3,5,7,9], [2,4,6,8]]

See also

memoize

memoize(callable $func): callable
memoizeWith(callable $resolver, callable $func): callable

Creates a function that memoizes the result of $func. $resolver returns map cache key, args[0] by default.

Arguments

$resolver
(...$args): string|int

See also

negate

negate(callable $predicate): callable

Creates a function that negates the result of the $predicate function.

Example

$isEven = fn ($n) => $n % 2 == 0;
filter(negate($isEven), [1, 2, 3, 4, 5, 6]); // [1, 3, 5]

Alias

  • complement

once

once(callable $fn): callable

$fn is only called once, the first value is returned in subsequent invocations.

Example

$addOneOnce = once(fn ($x) => $x + 1);
$addOneOnce(10); // 11
$addOneOnce(50); // 11

See also

partial

partial(callable $fn, array $partials): callable

Creates a function that invokes $fn with $partials prepended to the arguments. \Idles\_ const may be used as a placeholder.

Example

use const \Idles\_;

$abcd = fn ($a, $b, $c, $d) => $a.$b.$c.$d;
partial($abcd, ['a', _, 'c'])('b', 'd'); // 'abcd'

See also

partialRight

partialRight(callable $fn, array $partials): callable

Like partial but $partials are appended.

Example

use const \Idles\_;

$abcd = fn ($a, $b, $c, $d) => $a.$b.$c.$d;
partialRight($abcd, ['b', _, 'd'])('a', 'c')); // 'abcd'

See also

pipe

pipe(callable ...$funcs): callable
flow(array $funcs): callable

Left-to-right function composition. The first argument may have any arity; the remaining arguments must be unary.

Example

pipe('\trim', '\strtoupper')(' hello '); // 'HELLO'

See also

tap

tap(callable $interceptor, $value)

Calls $interceptor($value) then returns the original $value

See also

times

times(callable $iteratee, int $n): array

Calls the iteratee $n times, returning an array of the results of each invocation.

Arguments

$iteratee
(int $index): mixed

Example

times(fn($i) => "$i", 3); // ['0', '1', '2']

tryCatch

tryCatch(callable $tryer, callable $catcher, $value)

Calls $tryer, if it throws, calls $catcher

Arguments

$tryer
($value): mixed
$catcher
(\Exception $e, $value): mixed

Example

tryCatch(fn ($v) => "[$v]", fn ($err, $value) => [$err, $value])('A'); // '[A]'
tryCatch(
    fn ($v) => throw new \Exception('Error'),
    fn (\Exception $err, $value) => [$err->getMessage(), $value]
)('A'); // ['Error', 'A']

See also

unary

unary(callable $fn): callable

ary(1, $fn)

See also

Logic

allPass

allPass(array $predicates): callable

Returns a function that checks if its arguments pass all $predicates.

Arguments

$predicates
[(mixed ...$args): bool]

Example

$bothStrings = fn (...$args) => all(ary(1, '\is_string'), $args);
$equal = fn ($a, $b) => $a == $b;
allPass([$bothStrings, $equal])('a', 'b'); // false
allPass([$bothStrings, $equal])('a', 'a'); // true
allPass([$bothStrings, $equal])(1, 1); // false

Alias

  • overEvery

See also

anyPass

anyPass(array $predicates): callable

Returns a function that checks if its arguments pass any of the $predicates.

Arguments

$predicates
[(mixed ...$args): bool]

Example

$bothStrings = fn (...$args) => all(ary(1, '\is_string'), $args);
$equal = fn ($a, $b) => $a == $b;
anyPass([$bothStrings, $equal])('a', 'b'); // true
anyPass([$bothStrings, $equal])('1', 2); // false
anyPass([$bothStrings, $equal])(1, 1); // true

Alias

  • overSome

See also

both

both(callable $func1, callable $func2): callable

Resulting function returns $func1(...$args) if it is falsy or $func2(...$args) otherwise, short-circuited

Arguments

$func1
(mixed ...$args): mixed
$func2
(mixed ...$args): mixed

Example

both(identity(...), always(''))('value');  // ''
both(always('a'), identity(...))('b');     // b

See also

cond

cond(array $pairs): callable

Iterates over $pairs and invokes the corresponding function of the first predicate to return truthy.

Arguments

$pairs
[callable => callable]

Example

$fn = cond([
    [fn ($v) => $v == 0,    fn () => 'water freezes at 0°C'],
    [fn ($v) => $v == 100,  fn () => 'water boils at 100°C'],
    [fn () => true,         fn ($temp) => "nothing special happens at $temp °C"]
]);
$fn(0);     // 'water freezes at 0°C'
$fn(50);    // 'nothing special happens at 50 °C'
$fn(100);   // 'water boils at 100°C'

defaultTo

defaultTo($default)($value)

Returns $value ?? $default

Example

defaultTo(10, null); // 10

either

either(callable $func1, callable $func2): callable

Resulting function returns $func1(...$args) if it is truthy or $func2(...$args) otherwise, short-circuited.

Arguments

$func1
(mixed ...$args): mixed
$func2
(mixed ...$args): mixed

Example

either(always('a'), identity(...))('b');  // a
either(always(''), identity(...))('b');   // b

See also

ifElse

ifElse(callable $predicate, callable $onTrue, callable $onFalse): callable

Resulting function returns $onTrue(...$args) if $predicate(...$args) is truthy or $onFalse(...$args) otherwise.

Arguments

$predicate
(mixed ...$args): bool
$onTrue
(mixed ...$args): mixed
$onFalse
(mixed ...$args): mixed

Example

$f = ifElse(equals('a'), always('T'), always('F'));
$f('a');  // T
$f('b');  // F

See also

not

not($a): bool

returns !$a

See also

unless

unless(callable $predicate, callable $whenFalse, mixed $value)

Returns $predicate($value) ? $value : $whenFalse($value)

Arguments

$predicate
(mixed $value): bool
$whenFalse
(mixed $value): mixed

Example

$safeInc = unless(\is_null(...), inc(...));
$safeInc(null); // null
$safeInc(1);    // 2

See also

when

when(callable $predicate, callable $whenTrue, mixed $value)

Returns $predicate($value) ? $whenTrue($value) : $value

Arguments

$predicate
(mixed $value): bool
$whenTrue
(mixed $value): mixed

Example

$truncate = when(
    pipe(size(...), gt(_, 10)),
    pipe(partial(\mb_substr(...), [_, 0, 10]), fn ($s) => $s.'…')
);
$truncate('12345'); // '12345'
$truncate('0123456789ABC');  // '0123456789…'

See also

Math

add

add(int|float $a, int|float $b): int|float

$a + $b

Example

add(100)(13); // 113

See also

dec

dec(int $number): int

Returns $number - 1

See also

divide

divide(int|float $a, int|float $b): int|float

$a / $b

See also

gt

gt($a, $b): bool

$a > $b

Example

gt(100)(13); // true

See also

gte

gte($a, $b): bool

$a >= $b

Example

gte(13)(13); // true

See also

inc

inc(int $number): int

Returns $number + 1

See also

lt

lt($a, $b): bool

$a < $b

Example

lt(100)(13); // false

See also

lte

lte($a, $b): bool

$a <= $b

Example

lte(13)(13); // true

See also

modulo

modulo(int|float $a, int|float $b): int

$a % $b

See also

multiply

multiply(int|float $a, int|float $b): int|float

$a * $b

See also

round

round(int $precision, int|float $number): float

Rounds $numberto specified $precision

subtract

subtract(int|float $a, int|float $b): int|float

$a - $b

sum

sum(?iterable $collection)

Sums elements in iterable

Example

sum([4, 2, 8, 6]); // 20

See also

sumBy

sumBy(?callable $iteratee, ?iterable $collection)

Like sum but $iteratee is invoked for each element in iterable to generate the value to be summed.

Example

$ns = [[ 'n'=> 4 ], [ 'n'=> 2 ], [ 'n'=> 8 ], [ 'n'=> 6 ]];
sumBy(property('n'), $ns); // 20

See also

Record

assignDeep

assignDeep(array $iterables): array

Merges properties recursively, numeric keys are overwritten.

Example

$a = ['a' => ['b' => '1', 'c' => 'C'], ['e' => 'E'], 'x'];
$b = ['a' => ['b' => '2', 'd' => 'D'], ['f' => 'F'], 'y'];
assignDeep([$a, $b]);
// ['a' => ['b' => '2', 'c' => 'C', 'd' => 'D'], ['e' => 'E', 'f' => 'F'], 'y']

Alias

  • extendDeep

See also

defaults

defaults(?iterable $record1, ?iterable $record2): array
defaultsAll(array $iterables)

Merges properties from right to left, numeric keys are overwritten.

Example

defaultsAll([ ['actual', 'a'=>1], ['default', 'b'=>2], ['a'=>3] ]) // ['actual', 'a' => 1, 'b' => 2]

See also

evolve

evolve(array $transformations, ?iterable $record): array

Creates a new record by recursively calling transformation functions with $record properties.

Arguments

$transformations
[string|int => (mixed $value): mixed]

Example

$tomato = ['firstName' => '  Tomato ', 'data' => ['elapsed' => 100, 'remaining' => 1400], 'id' => 123];
$transformations = [
    'firstName' => '\trim',
    'lastName' => '\trim',  // Will not get invoked.
    'data' => [
        'elapsed' => add(1), 
        'remaining' => add(-1)
    ]
];
evolve($transformations)($tomato);
// ['firstName' => 'Tomato', 'data' =>  ['elapsed' =>  101, 'remaining' =>  1399], 'id' => 123]

See also

extend

extend(?iterable $source1, ?iterable $source2): array
extendAll(array $iterables): array

Merges properties, numeric keys are overwritten.

Example

extend(
    ['a', 'c' => 'C'], 
    ['b', 'd' => 'D']
); // ['b', 'c' => 'C', 'd' => 'D']

Aliases

  • assign,
  • assignAll

See also

has

has(string|int $key, ?iterable $record): bool

Checks if $record has $key

Example

$r = ['a' => 'A];
has('a', $r); // true

See also

hasPath

hasPath(string|int|array $path, ?iterable $record): bool

Checks if $path exists in $record

Example

$r = [ 'a' => [ 'b' => 2 ] ];
hasPath('a', $r); // true
hasPath('a.b', $r); // true
hasPath(['a', 'b'], $r); // true

See also

invert

invert(?iterable $collection): array

Replaces keys with values. Duplicate keys are overwritten.

Example

invert([ 'a' => 1, 'b' => 2, 'c' => 1 ]); // [1 => 'c', 2 => 'b']

keys

keys(?iterable $record): iterable

Returns an indexed iterable of keys in $record.

Example

keys([ 'a'=> 1, 'b'=> 2, 'c'=> 3 ]); // ['a', 'b', 'c']

See also

merge

merge(?iterable $source1, ?iterable $source2): array
mergeAll(array $iterables): array

Merges properties, numeric keys are appended.

Example

merge(['a', 'c' => 'C'], ['b', 'd' => 'D']); // ['a', 'b', 'c' => 'C', 'd' => 'D']

Alias

  • mergeRight

See also

mergeDeep

mergeDeep(array $iterables): array

Merges properties recursively, numeric keys are appended.

Example

$a = ['a' => ['b' => 1, 'c' => 'C'], ['e' => 'E'], 'x'];
$b = ['a' => ['b' => 2, 'd' => 'D'], ['f' => 'F'], 'y'];
mergeDeep([$a, $b]);
// ['a' => ['b' => [1, 2], 'c' => 'C', 'd' => 'D'], ['e' => 'E'], 'x', ['f' => 'F'], 'y'],

See also

mergeLeft

mergeLeft(?iterable $left, ?iterable $right): array

calls merge($right, $left)

Example

$resetToDefault = mergeLeft(['x' => 0]);
$resetToDefault(['x' => 5, 'y' => 2]); // ['x' => 0, 'y' => 2]

See also

mergeWith

mergeWith(callable $customizer, ?iterable $left, ?iterable $right): array

Like merge but if a key exists in both records, $customizer is called to the values associated with the key

Arguments

$customizer
(mixed $a, mixed $b): mixed

Example

mergeWith(concat(...), ['a' => [1], 'b' => [2]], ['a' => [3], 'b' => [4]]); // ['a' => [1,3], 'b' => [2,4]]

See also

modifyPath

modifyPath(array|string|int $path, callable $updater, ?iterable $record)

Creates new record by applying an $updater function to the value at the given $path.

Arguments

$updater
(mixed $value): mixed

Example

$a = [ 'a' => [ [ 'b' => [ 'c' => 3 ] ] ] ];
modifyPath(['a',0,'b','c'], fn ($n) => $n*$n, $a); // [ 'a' => [ [ 'b' => [ 'c' => 9 ] ] ] ]

Alias

  • update

See also

objOf

objOf(string $key, $value): array

Creates an array containing a single key => value pair.

Example

$matchPhrases = compose(
    objOf('must'),
    map(objOf('match_phrase'))
);
$matchPhrases(['foo', 'bar', 'baz']);
// ["must" => [["match_phrase" => 'foo'], ["match_phrase" => 'bar'], ["match_phrase" => 'baz']]]

omit

omit(array $keys, ?iterable $collection): iterable

The opposite of pick. Returns record without $keys.

Example

omit(['a', 'd'], ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4]);
// ['b' => 2, 'c' => 3]

See also

omitBy

omitBy(callable $predicate, ?iterable $record): iterable

The opposite of pickBy. Returns properties of $record that $predicate returns falsey for.

Example

omitBy(unary('\is_int'), ['a' => 1, 'b' => '2', 'c' => 3]); // ['b' => '2']

See also

path

path(array|string $path, ?iterable $collection)
pathOr($default, array|string $path, ?iterable $collection)

Retrieve the value at a given path.

Example

$rec = [ 'a' => [[ 'b' => [ 'c' => 3 ] ]] ];
path(['a', '0', 'b', 'c'], $rec); // 3
path('a[0].b.c', $rec); // 3
pathOr('default', 'a.b.c', $rec); // 'default'

Alias

  • get

See also

pick

pick(array $keys, ?iterable $collection): iterable

Returns record containing only $keys

Arguments

$keys
[string|int]

Example

pick(['a', 'd'], ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4]); 
// ['a' => 1, 'd' => 4]

See also

pickBy

pickBy(callable $predicate, ?iterable $record): iterable

Returns record containing only keys $predicate returns truthy for.

Arguments

$predicate
($value, $key): bool

Example

$isUpperCase = fn ($val, $key) => \strtoupper($key) == $key;
pickBy($isUpperCase, ['a' => 1, 'b' => 2, 'A' => 3, 'B' => 4]);
// ['A' => 3, 'B' => 4]

See also

pluck

pluck(string|int $key, ?iterable $collection)

Returns a new array by plucking the same named property off all records in the array supplied.

Example

pluck(0, [[1, 2], [3, 4]]); // [1, 3]
pluck('val', ['a' => ['val' => 3], 'b' => ['val' => 5]]); // ['a' => 3, 'b' => 5]

See also

prop

prop(string|int $key, ?iterable $record)
propOr($default, string|int $key, ?iterable $record)

Return the specified property.

Example

propOr('NO', 'b', ['a' => 'A']); // 'NO'

Alias

  • property

See also

propEq

propEq(string|int $key, $value, ?iterable $record): bool

Returns $record[$key] == $value

Example

propEq('a', 'A', ['a' => 'A']); // true

Alias

  • matchesProperty

See also

props

props(array $paths, ?iterable $collection): array

Keys in, values out. Order is preserved.

Example

$a = [ 'a' => [ [ 'b' => [ 'c' => 3 ] ], 4] ];
props(['a.0.b.c', 'a.0.z', 'a.1'], $a); // [3, null, 4]

Alias

  • at

See also

setPath

setPath($path, $value, ?iterable $record)

Return copy $record with $path set with $value

Example

$a   = [ 'a' => [ [ 'b' => [ 'c' => 3 ] ] ] ];
setPath(['a',0,'b','c'], 113, $a);  
// [ 'a' => [ [ 'b' => [ 'c' => 113 ] ] ] ]

Alias

  • assocPath

See also

toPairs

toPairs(?iterable $record): iterable

Converts a record into an array of [$key, $value]

Example

toPairs(['a' => 1, 'b' => 2, 'c' => 3]); // [['a', 1], ['b', 2], ['c', 3]]

Alias

  • entries

where

where(array $spec, ?iterable $record): bool

Checks if $record satisfies the spec by invoking the $spec properties with the corresponding properties of $record.

Arguments

$spec
[string => ($value): bool]

Example

$a = ['a' => 'A', 'b' => 'B'];
where(['a' => fn ($v) => $v == 'A'], $a); // true

Alias

  • conforms

See also

whereAny

whereAny(array $spec, ?iterable $record): bool

Checks if $record satisfies the spec by invoking the $spec properties with the corresponding properties of $record. Returns true if at least one of the predicates returns true.

Arguments

$spec
[string => ($value): bool]

Example

$objects = [
    [ 'a' => 2, 'b' => 1 ],
    [ 'a' => 1, 'b' => 2 ]
];
$pred = whereAny([
    'a' => gt(_, 10),
    'b' => lt(_, 2)
]);
filter($pred, $objects); // [[ 'a' => 2, 'b' => 1 ]]

See also

whereEq

whereEq(array $spec, ?iterable $test): bool

Check if the $test satisfies the $spec

Example

$pred = whereEq(['a' => 1, 'b' => 2]);
$pred(['a' => 1])); // false
$pred(['a' => 1, 'b' => 2])); // true
$pred(['a' => 1, 'b' => 2, 'c' => 3])); // true
$pred(['a' => 1, 'b' => 1]));   // false

Alias

  • matches

See also

String

escape

escape(string $s): string

Converts the characters "&", "<", ">", '"', and "'" to their corresponding HTML entities.

Example

escape('fred, barney, & pebbles'); // 'fred, barney, &amp; pebbles'

escapeRegExp

escapeRegExp(string $regexp): string

Escapes regular expression

split

split(string $separator, string $s): array

Splits string by $separator.

See also

startsWith

startsWith(string $target, string $s): bool

If string starts with $target.

See also

toLower

toLower(string $s): string

Converts string to lower case

toUpper

toUpper(string $s): string

Converts string to upper case

words

words(string $pattern, string $string): array

Splits string into an array of its words.

Arguments

$pattern
DON'T use /pattern/ delimiters

Example

words('\w+', 'aa bb cc'); // ['aa', 'bb', 'cc']

See also

Util

collect

collect(?iterable $iterable): array

Collects any iterable into array

eq

eq($a, $b): bool

$a == $b

Alias

  • identical

equals

equals($a, $b): bool

$a === $b

Alias

  • isEqual

F

F(...$args): bool

Always returns false

Alias

  • stubFalse

identity

identity($value)

Returns the first argument it receives.

See also

iterate

iterate(callable $f, $value): iterable

Returns a generator of $value, $f($value), $f($f($value)) etc.

Example

pipe(
    take(5),
    collect(...)
)(iterate(inc(...), 1)); // [1, 2, 3, 4, 5]

just

just($value): Optional

Returns an Optional with the specified non-null value

Example

just('abc')->map(\strtoupper(...))->get(); // ABC
just(113)
    ->filter(fn($n) => $n > 100)
    ->filter(fn($n) => $n < 120)
    ->get();    // 113

See also

nothing

nothing(): Optional

Returns an empty Optional

Example

nothing()->map(\strtoupper(...))->orElse('ABC'); // ABC

See also

now

now(): int

Returns the timestamp of the number of seconds

Optional

just(mixed $value): Optional
nothing(): Optional

Maybe/Option monad (container) which may or may not contain a non-null value. Has methods:

isPresent(): bool - true if not empty
isEmpty(): bool - true if empty
get(): mixed - returns value, throw exception if empty
orElse(mixed $default): mixed - returns the contained value if the optional is nonempty or $default
orElseThrow(Exception $e) - returns the contained value, if present, otherwise throw an exception
map(callable $f): Optional - If a value is present, apply the $f to it, and if the result is non-null, return an Optional describing the result
flatMap(callable $f): Optional - use instead of map if $f returns Optional
filter(callable $predicate): Optional - if a value is present and matches the $predicate, return an Optional with the value, otherwise an empty Optional.

See also

size

size(array|Countable|object|string|callable $value): int

Returns size of a countable, number of parameters of a function, lenght of string or number of properties of an object

Alias

  • length

T

T(...$args): bool

Always returns true

Alias

  • stubTrue