API¶
Static constructors¶
fromCallable¶
Create a collection from a callable.
$callback = static function () {
yield 'a';
yield 'b';
yield 'c';
};
$collection = Collection::fromCallable($callback);
fromIterable¶
Create a collection from an iterable.
$collection = Collection::fromIterable(['a', 'b', 'c']);
fromResource¶
Create a collection from a resource.
$stream = fopen('data://text/plain,' . $string, 'rb');
$collection = Collection::fromResource($stream);
fromString¶
Create a collection from a string.
$data = file_get_contents('http://loripsum.net/api');
$collection = Collection::fromString($data);
range¶
Build a collection from a range of values.
Signature: Collection::range(int $start = 0, $end = INF, $step = 1);
$fibonacci = static function ($a = 0, $b = 1): array {
return [$b, $a + $b];
};
$even = Collection::range(0, 20, 2); // [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Another example
$even = Collection::unfold(static function ($carry) {return $carry + 2;}, -2);
$odd = Collection::unfold(static function ($carry) {return $carry + 2;}, -1);
// Is the same as
$even = Collection::range(0, \INF, 2);
$odd = Collection::range(1, \INF, 2);
times¶
Create a collection by invoking a callback a given amount of times.
If no callback is provided, then it will create a simple list of incremented integers.
Signature: Collection::times($number = INF, ?callable $callback = null);
$collection = Collection::times(10);
unfold¶
Create a collection by yielding from a callback with a initial value.
Warning
The callback return values are reused as callback arguments at the next callback call.
Signature: Collection::unfold(callable $callback, ...$parameters);
// A list of Naturals from 1 to Infinity.
Collection::unfold(fn($n) => $n + 1, 1)
->normalize();
$fibonacci = static function ($a = 0, $b = 1): array {
return [$b, $a + $b];
};
Collection::unfold($fibonacci)
->limit(10); // [[0, 1], [1, 1], [1, 2], [2, 3], [3, 5], [5, 8], [8, 13], [13, 21], [21, 34], [34, 55]]
Another example
$even = Collection::unfold(static function (int $carry): int {return $carry + 2;}, -2);
$odd = Collection::unfold(static function (int $carry): int {return $carry + 2;}, -1);
// Is the same as
$even = Collection::range(0, \INF, 2);
$odd = Collection::range(1, \INF, 2);
Methods (operations)¶
Operations always returns a new collection object.
all¶
Convert the collection into an array.
This is a lossy operation because PHP array keys cannot be duplicated and must either be int or string.
Interface: Allable
Signature: Collection::all();
append¶
Add one or more items to a collection.
Warning
If appended values overwrite existing values, you might find that this operation doesn’t work correctly
when the collection is converted into an array.
It’s always better to never convert the collection to an array and use it in a loop.
However, if for some reason, you absolutely need to convert it into an array, then use the
Collection::normalize()
operation.
Interface: Appendable
Signature: Collection::append(...$items);
Collection::fromIterable([1 => '1', 2 => '2', 3 => '3'])
->append('4'); // [1 => '1', 2 => '2', 3 => '3', 0 => '4']
Collection::fromIterable(['1', '2', '3'])
->append('4')
->append('5', '6'); // [0 => 5, 1 => 6, 2 => 3]
Collection::fromIterable(['1', '2', '3'])
->append('4')
->append('5', '6')
->normalize(); // ['1', '2', '3', '4', '5', '6']
apply¶
Execute callback(s) on each element of the collection.
Iterates on the collection items regardless of the return value of the callback.
If the callback does not return true then it stops applying callbacks on subsequent items.
Interface: Applyable
Signature: Collection::apply(...$callbacks);
$callback = static function ($value, $key): bool
{
var_dump('Value is: ' . $value . ', key is: ' . $key);
return true;
};
$collection = Collection::fromIterable(['1', '2', '3']);
$collection
->apply($callback);
associate¶
Transform keys and values of the collection independently and combine them.
Interface: Associateable
Signature: Collection::associate(?callable $callbackForKeys = null, ?callable $callbackForValues = null);
$input = range(1, 10);
Collection::fromIterable($input)
->associate(
static function ($key, $value) {
return $key * 2;
},
static function ($key, $value) {
return $value * 2;
}
);
// [
// 0 => 2,
// 2 => 4,
// 4 => 6,
// 6 => 8,
// 8 => 10,
// 10 => 12,
// 12 => 14,
// 14 => 16,
// 16 => 18,
// 18 => 20,
// ]
asyncMap¶
Apply one callback to every item of a collection and use the return value.
Warning
Asynchronously apply callbacks to a collection. This operation is non-deterministic, we cannot ensure the elements order at the end.
Warning
Keys are preserved, use the “normalize” operation if you want to re-index the keys.
Interface: AsyncMapable
Signature: Collection::asyncMap(callable ...$callbacks);
$mapper1 = static function(int $value): int {
sleep($value);
return $value;
};
$mapper2 = static function(int $value): int {
return $value * 2;
};
$collection = Collection::fromIterable(['c' => 3, 'b' => 2, 'a' => 1])
->asyncMap($mapper1, $mapper2); // ['a' => 2, 'b' => 4, 'c' => 6]
cache¶
Useful when using a resource as input and you need to run through the collection multiple times.
Interface: Cacheable
Signature: Collection::cache(CacheItemPoolInterface $cache = null);
$fopen = fopen(__DIR__ . '/vendor/autoload.php', 'r');
$collection = Collection::fromResource($fopen)
->cache();
chunk¶
Chunk a collection of item into chunks of items of a given size.
Interface: Chunkable
Signature: Collection::chunk(int $size);
$collection = Collection::fromIterable(range(0, 10));
$collection->chunk(2);
collapse¶
Collapse a collection of items into a simple flat collection.
Interface: Collapseable
Signature: Collection::collapse();
$collection = Collection::fromIterable([[1,2], [3, 4]]);
$collection->collapse();
column¶
Return the values from a single column in the input iterables.
Interface: Columnable
Signature: Collection::column($index);
$records = [
[
'id' => 2135,
'first_name' => 'John',
'last_name' => 'Doe',
],
[
'id' => 3245,
'first_name' => 'Sally',
'last_name' => 'Smith',
],
[
'id' => 5342,
'first_name' => 'Jane',
'last_name' => 'Jones',
],
[
'id' => 5623,
'first_name' => 'Peter',
'last_name' => 'Doe',
],
];
$result = Collection::fromIterable($records)
->column('first_name');
combinate¶
Get all the combinations of a given length of a collection of items.
Interface: Combinateable
Signature: Collection::combinate(?int $length);
$collection = Collection::fromIterable(['a', 'b', 'c', 'd'])
->combinate(3);
combine¶
Combine a collection of items with some other keys.
Interface: Combineable
Signature: Collection::combine(...$keys);
$collection = Collection::fromIterable(['a', 'b', 'c', 'd'])
->combine('w', 'x', 'y', 'z')
compact¶
Remove given values from the collection, if no values are provided, it removes only the null value.
Interface: Compactable
Signature: Collection::compact(...$values);
$collection = Collection::fromIterable(['a', 1 => 'b', null, false, 0, 'c'];)
->compact(); // ['a', 1 => 'b', 3 => false, 4 => 0, 5 => 'c']
$collection = Collection::fromIterable(['a', 1 => 'b', null, false, 0, 'c'];)
->compact(null, 0); // ['a', 1 => 'b', 3 => false, 5 => 'c']
contains¶
Check if the collection contains one or more value.
Interface: Containsable
Signature: Collection::contains(...$value);
current¶
Get the value of an item in the collection given a numeric index, default index is 0.
Interface: Currentable
Signature: Collection::current(int $index = 0);
Collection::fromIterable(['a', 'b', 'c', 'd'])->current(); // Return 'a'
Collection::fromIterable(['a', 'b', 'c', 'd'])->current(0); // Return 'a'
Collection::fromIterable(['a', 'b', 'c', 'd'])->current(1); // Return 'b'
Collection::fromIterable(['a', 'b', 'c', 'd'])->current(10); // Return null
cycle¶
Cycle around a collection of items.
Interface: Cycleable
Signature: Collection::cycle(int $length = 0);
$collection = Collection::fromIterable(['a', 'b', 'c', 'd'])
->cycle(10)
diff¶
It compares the collection against another collection or a plain array based on its values. This method will return the values in the original collection that are not present in the given collection.
Interface: Diffable
Signature: Collection::diff(...$values);
$collection = Collection::fromIterable(['a', 'b', 'c', 'd', 'e'])
->diff('a', 'b', 'c', 'x'); // [3 => 'd', 4 => 'e']
diffKeys¶
It compares the collection against another collection or a plain object based on its keys. This method will return the key / value pairs in the original collection that are not present in the given collection.
Interface: Diffkeysable
Signature: Collection::diffKeys(...$values);
$collection = Collection::fromIterable(['a', 'b', 'c', 'd', 'e'])
->diffKeys(1, 2); // [0 => 'a', 3 => 'd', 4 => 'e']
distinct¶
Remove duplicated values from a collection.
Interface: Distinctable
Signature: Collection::distinct();
$collection = Collection::fromIterable(['a', 'b', 'c', 'd', 'a'])
->distinct()
drop¶
Drop the n first items of the collection.
Interface: Dropable
Signature: Collection::drop(int ...$counts);
Collection::fromIterable(range(10, 20))
->drop(2); // [12,13,14,15,16,17,18,19,20]
dropWhile¶
Iterate over the collection items and takes from it its elements from the moment when the condition fails for the first time till the end of the list.
Warning
The callbacks parameter is variadic and they are evaluated as a logical OR
.
If you’re looking for a logical AND
, you have make multiple calls to the
same operation.
Interface: DropWhileable
Signature: Collection::dropWhile(callable ...$callbacks);
$isSmallerThanThree = static function (int $value): bool {
return 3 > $value;
};
Collection::fromIterable([1,2,3,4,5,6,7,8,9,1,2,3])
->dropWhile($isSmallerThanThree); // [3,4,5,6,7,8,9,1,2,3]
duplicate¶
Find duplicated values from the collection.
Interface: Duplicateable
Signature: Collection::duplicate();
// It might returns duplicated values !
Collection::fromIterable(['a', 'b', 'c', 'a', 'c', 'a'])
->duplicate(); // [3 => 'a', 4 => 'c', 5 => 'a']
// Use ::distinct() and ::normalize() to get what you want.
Collection::fromIterable(['a', 'b', 'c', 'a', 'c', 'a'])
->duplicate()
->distinct()
->normalize() // [0 => 'a', 1 => 'c']
every¶
This operation tests whether all elements in the collection pass the test implemented by the provided callback(s).
Warning
The callbacks parameter is variadic and they are evaluated as a logical OR
.
If you’re looking for a logical AND
, you have make multiple calls to the
same operation.
Interface: Everyable
Signature: Collection::every(callable ...$callbacks);
$callback = static function ($value): bool {
return $value < 20;
};
Collection::fromIterable(range(0, 10))
->every($callback)
->current(); // true
Collection::fromIterable(range(0, 10))
->append(21)
->every($callback)
->current(); // false
Collection::fromIterable([])
->every($callback)
->current(); // true
explode¶
Explode a collection into subsets based on a given value.
This operation use the Split operation with the flag Splitable::REMOVE
and thus, values used to explode the
collection are removed from the chunks.
Interface: Explodeable
Signature: Collection::explode(...$items);
$string = 'I am just a random piece of text.';
$collection = Collection::fromIterable($string)
->explode('o');
falsy¶
Check if the collection contains falsy values.
Interface: Falsyable
Signature: Collection::falsy();
filter¶
Filter collection items based on one or more callbacks.
Interface: Filterable
Signature: Collection::filter(callable ...$callbacks);
$callback = static function($value): bool {
return 0 === $value % 3;
};
$collection = Collection::fromIterable(range(1, 100))
->filter($callback);
first¶
Get the first items from the collection.
Interface: Firstable
Signature: Collection::first();
$generator = static function (): Generator {
yield 'a' => 'a';
yield 'b' => 'b';
yield 'c' => 'c';
yield 'a' => 'd';
yield 'b' => 'e';
yield 'c' => 'f';
};
Collection::fromIterable($generator())
->first(); // ['a' => 'a']
flatten¶
Flatten a collection of items into a simple flat collection.
Interface: Flattenable
Signature: Collection::flatten(int $depth = PHP_INT_MAX);
$collection = Collection::fromIterable([0, [1, 2], [3, [4, [5, 6]]]])
->flatten();
flip¶
Flip keys and items in a collection.
Interface: Flipable
Signature: Collection::flip(int $depth = PHP_INT_MAX);
$collection = Collection::fromIterable(['a', 'b', 'c', 'a'])
->flip();
Tip
array_flip() and Collection::flip() can behave different, check the following examples.
When using regular arrays, array_flip() can be used to remove duplicates (dedup-licate an array).
$dedupArray = array_flip(array_flip(['a', 'b', 'c', 'd', 'a']));
This example will return ['a', 'b', 'c', 'd']
.
However, when using a collection:
$dedupCollection = Collection::fromIterable(['a', 'b', 'c', 'd', 'a'])
->flip()
->flip()
->all();
This example will return ['a', 'b', 'c', 'd', 'a']
.
foldLeft¶
Takes the initial value and the first item of the list and applies the function to them, then feeds the function with this result and the second argument and so on. See scanLeft for intermediate results.
Interface: FoldLeftable
Signature: Collection::foldLeft(callable $callback, $initial = null);
foldLeft1¶
Takes the first 2 items of the list and applies the function to them, then feeds the function with this result and the third argument and so on. See scanLeft1 for intermediate results.
Interface: FoldLeft1able
Signature: Collection::foldLeft1(callable $callback);
foldRight¶
Takes the initial value and the last item of the list and applies the function, then it takes the penultimate item from the end and the result, and so on. See scanRight for intermediate results.
Interface: FoldRightable
Signature: Collection::foldRight(callable $callback, $initial = null);
foldRight1¶
Takes the last two items of the list and applies the function, then it takes the third item from the end and the result, and so on. See scanRight1 for intermediate results.
Interface: FoldRight1able
Signature: Collection::foldRight1(callable $callback);
forget¶
Remove items having specific keys.
Interface: Forgetable
Signature: Collection::forget(...$keys);
$collection = Collection::fromIterable(range('a', 'z'))
->forget(5, 6, 10, 15);
frequency¶
Calculate the frequency of the values, frequencies are stored in keys.
Values can be anything (object, scalar, … ).
Interface: Frequencyable
Signature: Collection::frequency();
$collection = Collection::fromIterable(['a', 'b', 'c', 'b', 'c', 'c')
->frequency()
->all(); // [1 => 'a', 2 => 'b', 3 => 'c'];
get¶
Get a specific element of the collection from a key, if the key doesn’t exists, returns the default value.
Interface: Getable
Signature: Collection::get($key, $default = null);
group¶
Takes a list and returns a list of lists such that the concatenation of the result is equal to the argument. Moreover, each sublist in the result contains only equal elements.
Interface: Groupable
Signature: Collection::group();
Collection::fromString('Mississippi')
->group(); // [ [0 => 'M'], [1 => 'i'], [2 => 's', 3 => 's'], [4 => 'i'], [5 => 's', 6 => 's'], [7 => 'i'], [8 => 'p', 9 => 'p'], [10 => 'i'] ]
groupBy¶
Group items, the key used to group items can be customized in a callback. By default it’s the key is the item’s key.
Interface: GroupByable
Signature: Collection::groupBy(?callable $callback = null);
$callback = static function () {
yield 1 => 'a';
yield 1 => 'b';
yield 1 => 'c';
yield 2 => 'd';
yield 2 => 'e';
yield 3 => 'f';
};
$collection = Collection::fromIterable($callback)
->groupBy();
has¶
Check if the collection has values.
Warning
The callbacks parameter is variadic and they are evaluated as a logical OR
.
If you’re looking for a logical AND
, you have make multiple calls to the
same operation.
Interface: Hasable
Signature: Collection::has(callable ...$callbacks);
Collection::fromIterable(range('A', 'C'))
->has(
static fn ($value, $key, Iterator $iterator): string => 'A'
); // [true]
Collection::fromIterable(range('A', 'C'))
->has(
static fn ($value, $key, Iterator $iterator): string => 'D'
); // [false]
Collection::fromIterable(range('A', 'C'))
->has(
static fn ($value, $key, Iterator $iterator): string => 'A',
static fn ($value, $key, Iterator $iterator): string => 'Z'
); // [true]
head¶
Interface: Headable
Signature: Collection::head();
$generator = static function (): \Generator {
yield 1 => 'a';
yield 1 => 'b';
yield 1 => 'c';
yield 2 => 'd';
yield 2 => 'e';
yield 3 => 'f';
};
Collection::fromIterable($generator())
->head(); // [1 => 'a']
ifThenElse¶
Execute a callback when a condition is met.
Interface: IfThenElseable
Signature: Collection::ifThenElse(callable $condition, callable $then, ?callable $else = null);
$input = range(1, 5);
$condition = static function (int $value): bool {
return 0 === $value % 2;
};
$then = static function (int $value): int {
return $value * $value;
};
$else = static function (int $value): int {
return $value + 2;
};
Collection::fromIterable($input)
->ifThenElse($condition, $then); // [1, 4, 3, 16, 5]
Collection::fromIterable($input)
->ifThenElse($condition, $then, $else) // [3, 4, 5, 16, 7]
implode¶
Convert all the elements of the collection to a single string.
The glue character can be provided, default is the empty character.
Interface: Implodeable
Signature: Collection::implode(string $glue = '');
init¶
Returns the collection without its last item.
Interface: Initable
Signature: Collection::init();
Collection::fromIterable(range('a', 'e'))
->init(); // ['a', 'b', 'c', 'd']
inits¶
Returns all initial segments of the collection, shortest first.
Interface: Initsable
Signature: Collection::inits();
Collection::fromIterable(range('a', 'c'))
->inits(); // [[], ['a'], ['a', 'b'], ['a', 'b', 'c']]
intersect¶
Removes any values from the original collection that are not present in the given collection.
Interface: Intersectable
Signature: Collection::intersect(...$values);
$collection = Collection::fromIterable(range('a', 'e'))
->intersect('a', 'b', 'c'); // ['a', 'b', 'c']
intersectKeys¶
Removes any keys from the original collection that are not present in the given collection.
Interface: Intersectkeysable
Signature: Collection::intersectKeys(...$values);
$collection = Collection::fromIterable(range('a', 'e'))
->intersectKeys(0, 2, 4); // ['a', 'c', 'e']
intersperse¶
Insert a given value at every n element of a collection and indices are not preserved.
Interface: Intersperseable
Signature: Collection::intersperse($element, int $every = 1, int $startAt = 0);
$collection = Collection::fromIterable(range('a', 'z'))
->intersperse('foo', 3);
key¶
Get the key of an item in the collection given a numeric index, default index is 0.
Interface: Keyable
Signature: Collection::key(int $index = 0);
Collection::fromIterable(['a', 'b', 'c', 'd'])->key(); // Return 0
Collection::fromIterable(['a', 'b', 'c', 'd'])->key(0); // Return 0
Collection::fromIterable(['a', 'b', 'c', 'd'])->key(1); // Return 1
Collection::fromIterable(['a', 'b', 'c', 'd'])->key(10); // Return null
keys¶
Get the keys of the items.
Interface: Keysable
Signature: Collection::keys();
$collection = Collection::fromIterable(range('a', 'z'))
->keys();
last¶
Extract the last element of a collection, which must be finite and non-empty.
Interface: Lastable
Signature: Collection::last();
$generator = static function (): Generator {
yield 'a' => 'a';
yield 'b' => 'b';
yield 'c' => 'c';
yield 'a' => 'd';
yield 'b' => 'e';
yield 'c' => 'f';
};
Collection::fromIterable($generator())
->last(); // ['c' => 'f']
limit¶
Limit the amount of values in the collection.
Interface: Limitable
Signature: Collection::limit(int $limit);
$fibonacci = static function ($a = 0, $b = 1): array {
return [$b, $a + $b];
};
$collection = Collection::unfold($fibonacci)
->limit(10);
lines¶
Split a string into lines.
Interface: Linesable
Signature: Collection::lines();
$string = <<<'EOF'
The quick brow fox jumps over the lazy dog.
This is another sentence.
EOF;
Collection::fromString($string)
->lines();
map¶
Apply one or more supplied callbacks to every item of a collection and use the return value.
Warning
Keys are preserved, use the “normalize” operation if you want to re-index the keys.
Interface: Mapable
Signature: Collection::map(callable ...$callbacks);
$mapper = static function($value, $key) {
return $value * 2;
};
$collection = Collection::fromIterable(range(1, 100))
->map($mapper);
match¶
Check if the collection match a user callback
.
User must provide a callback that will get the key
, the current value
and the iterator
as parameters.
When no matcher callback is provided, the user callback must return true
(the
default value of the matcher callback
) in order to stop.
The returned value of the operation is true
when the callback match at least one element
of the collection. false
otherwise.
If you want to match the user callback
against another value (other than true
), you must
provide your own matcher callback
as a second argument, it must returns a boolean
.
Interface: Matchable
Signature: Collection::match(callable $callback, ?callable $matcher = null);
<?php
declare(strict_types=1);
namespace App;
use loophp\collection\Collection;
include __DIR__ . '/../../../../vendor/autoload.php';
// Example 1
$matcher = static function (int $value): bool {
return 10 > $value;
};
$collection = Collection::fromIterable(range(1, 100))
->match($matcher); // true
// Example 2
$matcher = static function (int $value): bool {
return 314 < $value;
};
$collection = Collection::fromIterable(range(1, 100))
->match($matcher); // false
// Example 3
$input = [
'Ningbo (CN)',
'California (US)',
'Brussels (EU)',
'New York (US)',
];
$pattern = '/\(EU\)$/';
$colletion = Collection::fromIterable($input)
->match(
static fn (string $value): bool => preg_match($pattern, $value)
); // true
merge¶
Merge one or more collection of items onto a collection.
Interface: Mergeable
Signature: Collection::merge(...$sources);
$collection = Collection::fromIterable(range(1, 10))
->merge(['a', 'b', 'c'])
normalize¶
Replace, reorder and use numeric keys on a collection.
Interface: Normalizeable
Signature: Collection::normalize();
$collection = Collection::fromIterable(['a' => 'a', 'b' => 'b', 'c' => 'c'])
->normalize();
nth¶
Get every n-th element of a collection.
Interface: Nthable
Signature: Collection::nth(int $step, int $offset = 0);
$collection = Collection::fromIterable(range(10, 100))
->nth(3);
nullsy¶
Check if the collection contains nullsy values.
Interface: Nullsyable
Signature: Collection::nullsy();
only¶
Get items having corresponding given keys.
Interface: Onlyable
Signature: Collection::only(...$keys);
$collection = Collection::fromIterable(range(10, 100))
->only(3, 10, 'a', 9);
pack¶
Wrap each items into an array containing 2 items: the key and the value.
Interface: Packable
Signature: Collection::pack();
$input = ['a' => 'b', 'c' => 'd', 'e' => 'f'];
$c = Collection::fromIterable($input)
->pack();
// [
// ['a', 'b'],
// ['c', 'd'],
// ['e', 'f'],
// ]
pad¶
Pad a collection to the given length with a given value.
Interface: Padable
Signature: Collection::pad(int $size, $value);
$collection = Collection::fromIterable(range(1, 5))
->pad(10, 'foo');
pair¶
Make an associative collection from pairs of values.
Interface: Pairable
Signature: Collection::pair();
$input = [
[
'key' => 'k1',
'value' => 'v1',
],
[
'key' => 'k2',
'value' => 'v2',
],
[
'key' => 'k3',
'value' => 'v3',
],
[
'key' => 'k4',
'value' => 'v4',
],
[
'key' => 'k4',
'value' => 'v5',
],
];
$c = Collection::fromIterable($input)
->unwrap()
->pair()
->group()
->all();
// [
// [k1] => v1
// [k2] => v2
// [k3] => v3
// [k4] => [
// [0] => v4
// [1] => v5
// ]
// ]
partition¶
With one or multiple callable, partition the items into 2 subgroups of items.
Warning
The callbacks parameter is variadic and they are evaluated as a logical OR
.
If you’re looking for a logical AND
, you have make multiple calls to the
same operation.
Interface: Partitionable
Signature: Collection::partition(callable ...$callbacks);
<?php
declare(strict_types=1);
namespace App;
include __DIR__ . '/../vendor/autoload.php';
use Closure;
use loophp\collection\Collection;
$isGreaterThan = static fn (int $left): Closure => static fn (int $right): bool => $left < $right;
$input = array_combine(range('a', 'l'), [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3]);
$collection = Collection::fromIterable($input)
->partition(
$isGreaterThan(5),
$isGreaterThan(3)
);
// Result
/*
[
[
['d', 4],
['e', 5],
['f', 6],
['g', 7],
['h', 8],
['i', 9],
],
[
['a', 1],
['b', 2],
['c', 3],
['j', 1],
['k', 2],
['l', 3],
],
]
*/
permutate¶
Find all the permutations of a collection.
Interface: Permutateable
Signature: Collection::permutate(int $size, $value);
$collection = Collection::fromIterable(['hello', 'how', 'are', 'you'])
->permutate();
pluck¶
Retrieves all of the values of a collection for a given key.
Interface: Pluckable
Signature: Collection::pluck($pluck, $default = null);
$fibonacci = static function ($a = 0, $b = 1): array {
return [$b, $a + $b];
};
$collection = Collection::unfold($fibonacci)
->limit(10)
->pluck(0);
prepend¶
Push an item onto the beginning of the collection.
Warning
If prepended values overwrite existing values, you might find that this operation doesn’t work correctly
when the collection is converted into an array.
It’s always better to never convert the collection to an array and use it in a loop.
However, if for some reason, you absolutely need to convert it into an array, then use the
Collection::normalize()
operation.
Interface: Prependable
Signature: Collection::prepend(...$items);
Collection::fromIterable([1 => '1', 2 => '2', 3 => '3'])
->prepend('4'); // [0 => 4, 1 => '1', 2 => '2', 3 => '3']
Collection::fromIterable(['1', '2', '3'])
->prepend('4')
->prepend('5', '6'); // [0 => 1, 1 => 2, 2 => 3]
Collection::fromIterable(['1', '2', '3'])
->prepend('4')
->prepend('5', '6')
->normalize(); // ['5', '6', '4', '1', '2', '3']
product¶
Get the the cartesian product of items of a collection.
Interface: Productable
Signature: Collection::product(iterable ...$iterables);
$collection = Collection::fromIterable(['4', '5', '6'])
->product(['1', '2', '3'], ['a', 'b'], ['foo', 'bar']);
random¶
It returns a random item from the collection.
An optional integer can be passed to random to specify how many items you would like to randomly retrieve. An optional seed can be passed as well.
Interface: Randomable
Signature: Collection::random(int $size = 1, ?int $seed = null);
$collection = Collection::fromIterable(['4', '5', '6'])
->random(); // ['6']
reduction¶
Reduce a collection of items through a given callback.
Interface: Reductionable
Signature: Collection::reduction(callable $callback, $initial = null);
$multiplication = static function ($value1, $value2) {
return $value1 * $value2;
};
$addition = static function ($value1, $value2) {
return $value1 + $value2;
};
$fact = static function (int $number) use ($multiplication) {
return Collection::range(1, $number + 1)
->reduce(
$multiplication,
1
);
};
$e = static function (int $value) use ($fact): float {
return $value / $fact($value);
};
$number_e_approximation = Collection::times()
->map($e)
->limit(10)
->reduction($addition);
reverse¶
Reverse order items of a collection.
Interface: Reverseable
Signature: Collection::reverse();
$collection = Collection::fromIterable(['a', 'b', 'c'])
->reverse();
rsample¶
Work in progress… sorry.
scale¶
Scale/normalize values.
Interface: Scaleable
Signature: Collection::scale(float $lowerBound, float $upperBound, ?float $wantedLowerBound = null, ?float $wantedUpperBound = null, ?float $base = null);
$collection = Collection::range(0, 10, 2)
->scale(0, 10);
$collection = Collection::range(0, 10, 2)
->scale(0, 10, 5, 15, 3);
scanLeft¶
Takes the initial value and the first item of the list and applies the function to them, then feeds the function with this result and the second argument and so on. It returns the list of intermediate and final results.
Interface: ScanLeftable
Signature: Collection::scanLeft(callable $callback, $initial = null);
$callback = static function ($carry, $value) {
return $carry / $value;
};
Collection::fromIterable([4, 2, 4])
->scanLeft($callback, 64)
->normalize(); // [64 ,16 ,8 ,2]
Collection::empty()
->scanLeft($callback, 3); // [0 => 3]
scanLeft1¶
Takes the first 2 items of the list and applies the function to them, then feeds the function with this result and the third argument and so on. It returns the list of intermediate and final results.
Warning
You might need to use the normalize
operation after this.
Interface: ScanLeft1able
Signature: Collection::scanLeft1(callable $callback);
$callback = static function ($carry, $value) {
return $carry / $value;
};
Collection::fromIterable([64, 4, 2, 8])
->scanLeft1($callback); // [64 ,16 ,8 ,1]
Collection::fromIterable([12])
->scanLeft1($callback); // [12]
scanRight¶
Takes the initial value and the last item of the list and applies the function, then it takes the penultimate item from the end and the result, and so on. It returns the list of intermediate and final results.
Interface: ScanRightable
Signature: Collection::scanRight(callable $callback, $initial = null);
$callback = static function ($carry, $value) {
return $value / $carry;
};
Collection::fromIterable([8, 12, 24, 4])
->scanRight($callback, 2); // [8, 1, 12, 2, 2]
Collection::empty()
->scanRight($callback, 3); // [3]
scanRight1¶
Takes the last two items of the list and applies the function, then it takes the third item from the end and the result, and so on. It returns the list of intermediate and final results.
Warning
You might need to use the normalize
operation after this.
Interface: ScanRight1able
Signature: Collection::scanRight1(callable $callback);
$callback = static function ($carry, $value) {
return $value / $carry;
};
Collection::fromIterable([8, 12, 24, 2])
->scanRight1($callback); // [8, 1, 12, 2]
Collection::fromIterable([12])
->scanRight1($callback); // [12]
shuffle¶
Shuffle a collection.
Interface: Shuffleable
Signature: Collection::shuffle(?int $seed = null);
$collection = Collection::fromIterable(['4', '5', '6'])
->random(); // ['6', '4', '5']
$collection = Collection::fromIterable(['4', '5', '6'])
->random(); // ['5', '6', '5']
since¶
Skip items until callback is met.
Warning
The callbacks parameter is variadic and they are evaluated as a logical OR
.
If you’re looking for a logical AND
, you have make multiple calls to the
same operation.
Interface: Sinceable
Signature: Collection::since(callable ...$callbacks);
// Example 1
// Parse the composer.json of a package and get the require-dev dependencies.
$collection = Collection::fromResource(fopen(__DIR__ . '/composer.json', 'rb'))
// Group items when EOL character is found.
->split(
Splitable::REMOVE,
static function (string $character): bool {
return "\n" === $character;
}
)
// Implode characters to create a line string
->map(
static function (array $characters): string {
return implode('', $characters);
}
)
// Skip items until the string "require-dev" is found.
->since(
static function ($line) {
return false !== strpos($line, 'require-dev');
}
)
// Skip items after the string "}" is found.
->until(
static function ($line) {
return false !== strpos($line, '}');
}
)
// Re-index the keys
->normalize()
// Filter out the first line and the last line.
->filter(
static function ($line, $index) {
return 0 !== $index;
},
static function ($line) {
return false === strpos($line, '}');
}
)
// Trim remaining results and explode the string on ':'.
->map(
static function ($line) {
return trim($line);
},
static function ($line) {
return explode(':', $line);
}
)
// Take the first item.
->pluck(0)
// Convert to array.
->all();
print_r($collection);
// Example 2
$input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3];
$isGreaterThanThree = static function (int $value): bool {
return 3 < $value;
};
$isGreaterThanEight = static function (int $value): bool {
return 8 < $value;
};
$collection = Collection::fromIterable($input)
->since(
$isGreaterThanThree,
$isGreaterThanEight
); // [4, 5, 6, 7, 8, 9, 1, 2, 3]
$collection = Collection::fromIterable($input)
->since(
$isGreaterThanThree
)
->since(
$isGreaterThanEight
); // [9, 1, 2, 3]
slice¶
Get a slice of a collection.
Interface: Sliceable
Signature: Collection::slice(int $offset, ?int $length = null);
$collection = Collection::fromIterable(range('a', 'z'))
->slice(5, 5);
sort¶
Sort a collection using a callback. If no callback is provided, it will sort using natural order.
By default, it will sort by values and using a callback. If you want to sort by keys, you can pass a parameter to change the behavior or use twice the flip operation. See the example below.
Interface: Sortable
Signature: Collection::sort(?callable $callback = null);
// Regular values sorting
$collection = Collection::fromIterable(['z', 'y', 'x'])
->sort();
// Regular values sorting
$collection = Collection::fromIterable(['z', 'y', 'x'])
->sort(Operation\Sortable::BY_VALUES);
// Regular values sorting with a custom callback
$collection = Collection::fromIterable(['z', 'y', 'x'])
->sort(
Operation\Sortable::BY_VALUES,
static function ($left, $right): int {
// Do the comparison here.
return $left <=> $right;
}
);
// Regular keys sorting (no callback is needed here)
$collection = Collection::fromIterable(['z', 'y', 'x'])
->sort(
Operation\Sortable::BY_KEYS
);
// Regular keys sorting using flip() operations.
$collection = Collection::fromIterable(['z', 'y', 'x'])
->flip() // Exchange values and keys
->sort() // Sort the values (which are now the keys)
->flip(); // Flip again to put back the keys and values, sorted by keys.
span¶
Returns a tuple where first element is longest prefix (possibly empty) of elements that satisfy the callback and second element is the remainder.
Interface: Spanable
Signature: Collection::span(callable $callback);
$input = range(1, 10);
Collection::fromIterable($input)
->span(fn ($x) => $x < 4); // [ [1, 2, 3], [4, 5, 6, 7, 8, 9, 10] ]
split¶
Split a collection using one or more callbacks.
A flag must be provided in order to specify whether the value used to split the collection should be added at the end of a chunk, at the beginning of a chunk, or completely removed.
Interface: Splitable
Signature: Collection::split(int $type = Splitable::BEFORE, callable ...$callbacks);
$splitter = static function ($value): bool {
return 0 === $value % 3;
};
$collection = Collection::fromIterable(range(0, 10))
->split(Splitable::BEFORE, $splitter); [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]
$collection = Collection::fromIterable(range(0, 10))
->split(Splitable::AFTER, $splitter); [[0], [1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
$collection = Collection::fromIterable(range(0, 10))
->split(Splitable::REMOVE, $splitter); [[1, 2], [4, 5], [7, 8], [10]]
tail¶
Get the collection items except the first.
Interface: Tailable
Signature: Collection::tail();
Collection::fromIterable(['a', 'b', 'c'])
->tail(); // [1 => 'b', 2 => 'c']
tails¶
Returns the list of initial segments of its argument list, shortest last.
Interface: Tailsable
Signature: Collection::tails();
Collection::fromIterable(['a', 'b', 'c'])
->tails(); // [['a', 'b', 'c'], ['b', 'c'], ['c'], []]
takeWhile¶
Iterate over the collection items when the provided callback(s) are satisfied.
It stops iterating when the callback(s) are not met.
Warning
The callbacks parameter is variadic and they are evaluated as a logical OR
.
If you’re looking for a logical AND
, you have make multiple calls to the
same operation.
Be careful, this operation is not the same as the filter
operation.
Interface: TakeWhileable
Signature: Collection::takeWhile(callable ...$callbacks);
$isSmallerThanThree = static function (int $value): bool {
return 3 > $value;
};
Collection::fromIterable([1,2,3,4,5,6,7,8,9,1,2,3])
->takeWhile($isSmallerThanThree); // [1,2]
transpose¶
Matrix transposition.
Interface: Transposeable
Signature: Collection::transpose();
$records = [
[
'id' => 2135,
'first_name' => 'John',
'last_name' => 'Doe',
],
[
'id' => 3245,
'first_name' => 'Sally',
'last_name' => 'Smith',
],
[
'id' => 5342,
'first_name' => 'Jane',
'last_name' => 'Jones',
],
[
'id' => 5623,
'first_name' => 'Peter',
'last_name' => 'Doe',
],
];
$result = Collection::fromIterable($records)
->transpose();
truthy¶
Check if the collection contains truthy values.
Interface: Truthyable
Signature: Collection::truthy();
unlines¶
Create a string from lines.
Interface: Unlinesable
Signature: Collection::unlines();
$lines = [
'The quick brow fox jumps over the lazy dog.',
'',
'This is another sentence.',
];
Collection::fromIterable($lines)
->unlines()
->current();
unpack¶
Unpack items.
Interface: Unpackable
Signature: Collection::unpack();
$input = [['a', 'b'], ['c', 'd'], ['e', 'f']];
$c = Collection::fromIterable($input)
->unpack();
// [
// ['a' => 'b'],
// ['c' => 'd'],
// ['e' => 'f'],
// ];
unpair¶
Unpair a collection of pairs.
Interface: Unpairable
Signature: Collection::unpair();
$input = [
'k1' => 'v1',
'k2' => 'v2',
'k3' => 'v3',
'k4' => 'v4',
];
$c = Collection::fromIterable($input)
->unpair();
// [
// ['k1', 'v1'],
// ['k2', 'v2'],
// ['k3', 'v3'],
// ['k4', 'v4'],
// ];
until¶
Iterate over the collection items until the provided callback(s) are satisfied.
Warning
The callbacks parameter is variadic and they are evaluated as a logical OR
.
If you’re looking for a logical AND
, you have make multiple calls to the
same operation.
Interface: Untilable
Signature: Collection::until(callable ...$callbacks);
// The Collatz conjecture (https://en.wikipedia.org/wiki/Collatz_conjecture)
$collatz = static function (int $value): int
{
return 0 === $value % 2 ?
$value / 2:
$value * 3 + 1;
};
$collection = Collection::unfold($collatz, 10)
->until(static function ($number): bool {
return 1 === $number;
});
unwindow¶
Contrary of Collection::window()
, usually needed after a call to that operation.
Interface: Unwindowable
Signature: Collection::unwindow();
// Drop all the items before finding five 9 in a row.
$input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
Collection::fromIterable($input)
->window(4)
->dropWhile(
static function (array $value): bool {
return $value !== [9, 9, 9, 9, 9];
}
)
->unwindow()
->drop(1)
->normalize(); // [10, 11, 12, 13, 14, 15, 16, 17, 18]
unwords¶
Create a string from words.
Interface: Unwordsable
Signature: Collection::unwords();
$words = [
'The',
'quick',
'brow',
'fox',
'jumps',
'over',
'the',
'lazy',
"dog.\n\nThis",
'is',
'another',
'sentence.',
];
Collection::fromIterable($words)
->unwords();
unwrap¶
Unwrap every collection element.
Interface: Unwrapable
Signature: Collection::unwrap();
$data = [['a' => 'A'], ['b' => 'B'], ['c' => 'C']];
$collection = Collection::fromIterable($data)
->unwrap();
unzip¶
Unzip a collection.
Interface: Unzipable
Signature: Collection::unzip();
$a = Collection::fromIterable(['a' => 'a', 'b' => 'b', 'c' => 'c'])
->zip(['d', 'e', 'f', 'g'], [1, 2, 3, 4, 5]);
$b = Collection::fromIterable($a)
->unzip(); // [ ['a','b','c',null,null], ['d','e','f','g',null], [1,2,3,4,5] ]
window¶
Loop the collection by yielding a specific window of data of a given length.
Interface: Windowable
Signature: Collection::window(int $size);
$data = range('a', 'z');
Collection::fromIterable($data)
->window(2)
->all(); // [ ['a'], ['a', 'b'], ['b', 'c'], ['c', 'd'], ... ]
words¶
Get words from a string.
Interface: Wordsable
Signature: Collection::words();
$string = <<<'EOF'
The quick brow fox jumps over the lazy dog.
This is another sentence.
EOF;
Collection::fromString($string)
->words()
wrap¶
Wrap every element into an array.
Interface: Wrapable
Signature: Collection::wrap();
$data = ['a' => 'A', 'b' => 'B', 'c' => 'C'];
$collection = Collection::fromIterable($data)
->wrap();
zip¶
Zip a collection together with one or more iterables.
Interface: Zipable
Signature: Collection::zip(iterable ...$iterables);
$even = Collection::range(0, INF, 2);
$odd = Collection::range(1, INF, 2);
$positiveIntegers = Collection::fromIterable($even)
->zip($odd)
->limit(100)
->unwrap(); // [0, 1, 2, 3 ... 196, 197, 198, 199]