A fast and simple PHP 7.1+ collection library.
composer require nztm/collection
You can create a collection by passing a iterable
value:
// Arrays
new Collection([1, 2, 3]);
// Generators
new Collection(function () {
yield 1;
yield 2;
yield 3;
});
// Traversables
new Collection(new class implements \IteratorAggregate {
public function getIterator(): iterable
{
return new \ArrayIterator([1, 2, 3]);
}
});
To create an empty collection, pass no arguments:
$c = new Collection();
all
average
chunk
count
diff
each
every
filter
first
get
has
implode
intersect
isEmpty
keys
last
map
reduce
reverse
slice
some
sum
values
without
Get all items as an array.
$c = new Collection([1, 2, 3]);
$c->all();
// [1, 2, 3]
Get the average value of the items.
$c = new Collection([1, 5, 7, 10]);
$c->average();
// 5.75
If the collection is empty, average
will throw an EmptyCollectionException
.
Break the items into chunks.
$c = new Collection([1, 2, 3, 4, 5, 6, 7, 8]);
$c->chunk(3);
// Collection([
// 0 => Collection([0 => 1, 1 => 2, 2 => 3])
// 1 => Collection([3 => 4, 4 => 5, 5 => 6])
// 2 => Collection([6 => 7, 7 => 8])
// ])
Count the number of items.
$c = new Collection(['a', 'b', 'c', 'd']);
$c->count();
// 4
Get the difference between items.
$a = new Collection([1, 2, 3, 4, 5]);
$b = new Collection([2, 3, 4]);
$a->diff($b);
// Collection([0 => 1, 4 => 5])
diff
accepts a variable amount of arguments:
$a = new Collection([1, 2, 3, 4, 5]);
$b = new Collection([2, 3, 4]);
$c = new Collection([1]);
$a->diff($b, $c);
// Collection([4 => 5])
Run a function for each item.
$c = new Collection([1, 2, 3]);
$c->each(function (int $number) {
echo $number."\n";
});
// 1
// 2
// 3
You can stop a loop's execution (like break
in a foreach
) by returning false
:
$c = new Collection([1, 2, 3, 4, 5, 6]);
$c->each(function (int $number) {
if ($number === 4) {
return false;
}
echo $number."\n";
});
// 1
// 2
// 3
You can access the key of the current item with the second parameter:
$c->each(function ($value, $key) {
//
});
// a = 1
// b = 2
Ensure every item passes a truth test.
$c = new Collection([2, 4, 6, 8]);
$isEven = function (int $number) {
return $number % 2 === 0;
});
$c->every($isEven);
// true
You can access the key of the current item with the second parameter:
$c->every(function ($value, $key) {
//
});
Filter items.
$c = new Collection([1, 2, 3, 4, 5, 6, 7, 8]);
$isEven = function (int $number) {
return $number % 2 === 0;
});
$c->filter($isEven);
// Collection([2, 4, 6, 8])
You can access the key of the current item with the second parameter:
$c->filter(function ($value, $key) {
//
});
You can also omit the callback completely to filter all falsey values:
$c = new Collection([false, 1, 0, '', 'foo']);
$c->filter();
// Collection([1 => 1, 4 => 'foo'])
Get the first item.
$c = new Collection([1, 2, 3]);
$c->first();
// 1
If the collection is empty, first
will throw an EmptyCollectionException
.
Get the value at the given key.
$c = new Collection([
'foo' => 1,
'bar' => 2,
]);
$c->get('foo');
// 1
If the key doesn't exist, get
will return null
:
$c = new Collection([
'foo' => 1,
]);
$c->get('bar');
// null
Determine if a key exists.
$c = new Collection([
'foo' => 1,
]);
$c->has('foo');
// true
$c->has('bar');
// false
Implode items to a string.
$c = new Collection(['foo', 'bar', 'baz']);
$c->implode('|');
// foo|bar|baz
If you don't pass an argument, it implodes using an empty string (''
):
$c = new Collection(['foo', 'bar', 'baz']);
$c->implode();
// foobarbaz
Find intersecting items.
$a = new Collection(['strawberry', 'apple', 'pear']);
$b = new Collection(['pineapple', 'pear', 'banana']);
$c = new Collection(['banana', 'raspberry', 'cherry']);
$a->intersect($b, $c);
// Collection(['pear', 'banana'])
Determine if the collection is empty.
$c = new Collection([1, 2, 3]);
$c->isEmpty();
// false
$c = new Collection([]);
$c->isEmpty();
// true
Get the keys of the items.
$c = new Collection([
'foo' => 1,
'bar' => 2,
]);
$c->keys();
// Collection(['foo', 'bar'])
Get the last item.
$c = new Collection([1, 2, 3, 4, 5]);
$c->last();
// 5
If the collection is empty, last
will throw an EmptyCollectionException
.
Map the items.
$c = new Collection([1, 2, 3, 4]);
$c->map(function (int $number) {
return $number * 2;
});
// Collection([2, 4, 6, 8])
$c = new Collection(['foo', 'bar', 'baz']);
$c->map('strtoupper');
// Collection(['FOO', 'BAR', 'BAZ'])
You can access the key of the current item with the second parameter:
$c->map(function ($value, $key) {
//
});
Reduce items to a single value. The second parameter sets the starting value, which is null
if not supplied.
$c = new Collection([5, 10, 20])
$c->reduce(function (int $carry, int $number) {
return $carry + $number;
}, 0);
// 35
You can access the key of the current item with the third parameter:
$c->map(function ($carry, $value, $key) {
//
});
Reverse the order of the items.
$c = new Collection([1, 2, 3]);
$c->reverse();
// Collection([2 => 3, 1 => 2, 0 => 1])
Extract a slice of the items.
$c = new Collection([1, 2, 3, 4, 5, 6]);
$c->slice(2);
// Collection([2 => 3, 3 => 4, 4 => 5, 5 => 6])
You can specify a length with the second parameter:
$c = new Collection([1, 2, 3, 4, 5, 6]);
$c->slice(2, 2);
// Collection([2 => 3, 3 => 4])
Determine if one or more of the items passes a truth test.
$c = new Collection([1, 3, 5, 6, 7, 9]);
$c->some(function (int $number) {
return $number % 2 === 0;
});
// true
$c->some(function (int $number) {
return $number > 10;
});
// false
You can access the key of the current item with the second parameter:
$c->some(function ($value, $key) {
//
});
Get a sum of the items.
$c = new Collection([1, 2, 3, 4, 5]);
$c->sum();
// 15
Get the values of the items.
$c = new Collection([
'foo' => 1,
'bar' => 2,
'baz' => 3,
]);
$c->values();
// Collection([1, 2, 3])
Create a new collection without the given keys.
$c = new Collection([
'foo' => 1,
'bar' => 2,
'baz' => 3,
]);
$c->without(['foo', 'baz']);
// Collection(['bar' => 2])