Класс Illuminate\Support\Collection
обеспечивает гибкую и удобную обертку для работы с массивами данных. Например, посмотрите на следующий код. Здесь мы будем использовать помощник collect
, чтобы создать новый экземпляр коллекции из массива, запустим функцию strtoupper
для каждого элемента, а затем удалим все пустые элементы:
$collection = collect(['taylor', 'abigail', null])->map(function ($name) {
return strtoupper($name);
})->reject(function ($name) {
return empty($name);
});
Как видите, класс Collection
позволяет объединять необходимые вам методы в цепочку для выполнения последовательного перебора и сокращения базового массива. В-основном коллекции неизменяемы, то есть каждый метод коллекции возвращает совершенно новый экземпляр Collection
.
Как упоминалось выше, помощник collect
возвращает новый экземпляр Illuminate\Support\Collection
для переданного массива. Итак, создать коллекцию очень просто:
$collection = collect([1, 2, 3]);
{tip} Результаты запросов Eloquent всегда возвращаются как экземпляры
Collection
.
Класс Collection
являются «макропрограммируемым», что позволяет вам добавлять дополнительные методы к классу во время выполнения. Метод macro
класса Illuminate\Support\Collection
принимает замыкание, которое будет выполнено при вызове вашей макрокоманды. Замыкание макрокоманды может обращаться к другим методам коллекции через $this
, как если бы это был реальный метод класса коллекции. Например, следующий код добавляет метод toUpper
классу Collection
:
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
Collection::macro('toUpper', function () {
return $this->map(function ($value) {
return Str::upper($value);
});
});
$collection = collect(['first', 'second']);
$upper = $collection->toUpper();
// ['FIRST', 'SECOND']
Обычно вы должны объявлять макрокоманды коллекций в методе boot
поставщика служб.
При необходимости вы можете определить макрокоманды, которые принимают дополнительные аргументы:
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Lang;
Collection::macro('toLocale', function ($locale) {
return $this->map(function ($value) use ($locale) {
return Lang::get($value, [], $locale);
});
});
$collection = collect(['first', 'second']);
$translated = $collection->toLocale('es');
В большей части оставшейся документации по коллекциям мы обсудим каждый метод, доступный в классе Collection
. Помните, что все эти методы можно объединить в цепочку для последовательного управления базовым массивом. Более того, почти каждый метод возвращает новый экземпляр Collection
, позволяя вам при необходимости сохранить исходную копию коллекции:
- all
- average
- avg
- chunk
- chunkWhile
- collapse
- collect
- combine
- concat
- contains
- containsStrict
- count
- countBy
- crossJoin
- dd
- diff
- diffAssoc
- diffKeys
- dump
- duplicates
- duplicatesStrict
- each
- eachSpread
- every
- except
- filter
- first
- firstWhere
- flatMap
- flatten
- flip
- forget
- forPage
- get
- groupBy
- has
- implode
- intersect
- intersectByKeys
- isEmpty
- isNotEmpty
- join
- keyBy
- keys
- last
- macro
- make
- map
- mapInto
- mapSpread
- mapToGroups
- mapWithKeys
- max
- median
- merge
- mergeRecursive
- min
- mode
- nth
- only
- pad
- partition
- pipe
- pipeInto
- pluck
- pop
- prepend
- pull
- push
- put
- random
- reduce
- reject
- replace
- replaceRecursive
- reverse
- search
- shift
- shuffle
- skip
- skipUntil
- skipWhile
- slice
- sliding
- sole
- some
- sort
- sortBy
- sortByDesc
- sortDesc
- sortKeys
- sortKeysDesc
- splice
- split
- splitIn
- sum
- take
- takeUntil
- takeWhile
- tap
- times
- toArray
- toJson
- transform
- union
- unique
- uniqueStrict
- unless
- unlessEmpty
- unlessNotEmpty
- unwrap
- values
- when
- whenEmpty
- whenNotEmpty
- where
- whereStrict
- whereBetween
- whereIn
- whereInStrict
- whereInstanceOf
- whereNotBetween
- whereNotIn
- whereNotInStrict
- whereNotNull
- whereNull
- wrap
- zip
Метод all
возвращает базовый массив, представленный коллекцией:
collect([1, 2, 3])->all();
// [1, 2, 3]
Псевдоним для метода avg
.
Метод avg
возвращает среднее значение переданного ключа:
$average = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->avg('foo');
// 20
$average = collect([1, 1, 2, 4])->avg();
// 2
Метод chunk
разбивает коллекцию на несколько меньших коллекций указанного размера:
$collection = collect([1, 2, 3, 4, 5, 6, 7]);
$chunks = $collection->chunk(4);
$chunks->all();
// [[1, 2, 3, 4], [5, 6, 7]]
Этот метод особенно полезен в шаблонах при работе с сеткой, такой как Bootstrap. Например, представьте, что у вас есть коллекция моделей Eloquent, которые вы хотите отобразить в сетке:
@foreach ($products->chunk(3) as $chunk)
<div class="row">
@foreach ($chunk as $product)
<div class="col-xs-4">{{ $product->name }}</div>
@endforeach
</div>
@endforeach
Метод chunkWhile
разбивает коллекцию на несколько меньших по размеру коллекций на основе результата переданного замыкания. Переменная $chunk
, переданная в замыкание, может использоваться для проверки предыдущего элемента:
$collection = collect(str_split('AABBCCCD'));
$chunks = $collection->chunkWhile(function ($value, $key, $chunk) {
return $value === $chunk->last();
});
$chunks->all();
// [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]
Метод collapse
сворачивает коллекцию массивов в единую плоскую коллекцию:
$collection = collect([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]);
$collapsed = $collection->collapse();
$collapsed->all();
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
Метод collect
возвращает новый экземпляр Collection
с элементами, находящимися в текущей коллекции:
$collectionA = collect([1, 2, 3]);
$collectionB = $collectionA->collect();
$collectionB->all();
// [1, 2, 3]
Метод collect
в первую очередь полезен для преобразования отложенных коллекций в стандартные экземпляры Collection
:
$lazyCollection = LazyCollection::make(function () {
yield 1;
yield 2;
yield 3;
});
$collection = $lazyCollection->collect();
get_class($collection);
// 'Illuminate\Support\Collection'
$collection->all();
// [1, 2, 3]
{tip} Метод
collect
особенно полезен, когда у вас есть экземплярEnumerable
и вам нужен «не-отложенный» экземпляр коллекции. Так какcollect()
является частью контрактаEnumerable
, вы можете безопасно использовать его для получения экземпляраCollection
.
Метод combine
объединяет значения коллекции в качестве ключей со значениями другого массива или коллекции:
$collection = collect(['name', 'age']);
$combined = $collection->combine(['George', 29]);
$combined->all();
// ['name' => 'George', 'age' => 29]
Метод concat
добавляет значения переданного массива или коллекции в конец другой коллекции:
$collection = collect(['John Doe']);
$concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']);
$concatenated->all();
// ['John Doe', 'Jane Doe', 'Johnny Doe']
Метод contains
определяет, содержит ли коллекция переданный элемент. Вы также можете передать замыкание в contains
, чтобы определить, существует ли в коллекции элемент, соответствующий указанному критерию истинности:
$collection = collect([1, 2, 3, 4, 5]);
$collection->contains(function ($value, $key) {
return $value > 5;
});
// false
Как вариант, вы можете передать строку методу contains
, чтобы определить, содержит ли коллекция указанное значение элемента:
$collection = collect(['name' => 'Desk', 'price' => 100]);
$collection->contains('Desk');
// true
$collection->contains('New York');
// false
Вы также можете передать пару ключ / значение методу contains
, который определит, существует ли данная пара в коллекции:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
]);
$collection->contains('product', 'Bookcase');
// false
Метод contains
использует «гибкое» сравнение при проверке значений элементов, то есть строка с целочисленным значением будет считаться равной целому числу того же значения. Используйте метод containsStrict
для фильтрации с использованием «жесткого» сравнения.
Этот метод имеет ту же сигнатуру, что и метод contains
; однако, все значения сравниваются с использованием «жесткого» сравнения.
{tip} Поведение этого метода изменяется при использовании коллекций Eloquent.
Метод count
возвращает общее количество элементов в коллекции:
$collection = collect([1, 2, 3, 4]);
$collection->count();
// 4
Метод countBy
подсчитывает вхождения значений в коллекцию. По умолчанию метод подсчитывает вхождения каждого элемента, что позволяет подсчитать определенные «типы» элементов в коллекции:
$collection = collect([1, 2, 2, 2, 3]);
$counted = $collection->countBy();
$counted->all();
// [1 => 1, 2 => 3, 3 => 1]
Вы можете передать замыкание методу countBy
для подсчета всех элементов по собственным критериям:
$collection = collect(['[email protected]', '[email protected]', '[email protected]']);
$counted = $collection->countBy(function ($email) {
return substr(strrchr($email, "@"), 1);
});
$counted->all();
// ['gmail.com' => 2, 'yahoo.com' => 1]
Метод crossJoin
перекрестно соединяет значения коллекции среди переданных массивов или коллекций, возвращая декартово произведение со всеми возможными перестановками:
$collection = collect([1, 2]);
$matrix = $collection->crossJoin(['a', 'b']);
$matrix->all();
/*
[
[1, 'a'],
[1, 'b'],
[2, 'a'],
[2, 'b'],
]
*/
$collection = collect([1, 2]);
$matrix = $collection->crossJoin(['a', 'b'], ['I', 'II']);
$matrix->all();
/*
[
[1, 'a', 'I'],
[1, 'a', 'II'],
[1, 'b', 'I'],
[1, 'b', 'II'],
[2, 'a', 'I'],
[2, 'a', 'II'],
[2, 'b', 'I'],
[2, 'b', 'II'],
]
*/
Метод dd
выводит элементы коллекции и завершает выполнение скрипта:
$collection = collect(['John Doe', 'Jane Doe']);
$collection->dd();
/*
Collection {
#items: array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
}
*/
Если вы не хотите останавливать выполнение вашего скрипта, используйте вместо этого метод dump
.
Метод diff
сравнивает коллекцию с другой коллекцией или простым массивом PHP на основе его значений. Этот метод вернет значения из исходной коллекции, которых нет в переданной коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$diff = $collection->diff([2, 4, 6, 8]);
$diff->all();
// [1, 3, 5]
{tip} Поведение этого метода изменяется при использовании коллекций Eloquent.
Метод diffAssoc
сравнивает коллекцию с другой коллекцией или простым массивом PHP на основе его ключей и значений. Этот метод вернет пары ключ / значение из исходной коллекции, которых нет в переданной коллекции:
$collection = collect([
'color' => 'orange',
'type' => 'fruit',
'remain' => 6,
]);
$diff = $collection->diffAssoc([
'color' => 'yellow',
'type' => 'fruit',
'remain' => 3,
'used' => 6,
]);
$diff->all();
// ['color' => 'orange', 'remain' => 6]
Метод diffKeys
сравнивает коллекцию с другой коллекцией или простым массивом PHP на основе его ключей. Этот метод вернет пары ключ / значение из исходной коллекции, которых нет в переданной коллекции:
$collection = collect([
'one' => 10,
'two' => 20,
'three' => 30,
'four' => 40,
'five' => 50,
]);
$diff = $collection->diffKeys([
'two' => 2,
'four' => 4,
'six' => 6,
'eight' => 8,
]);
$diff->all();
// ['one' => 10, 'three' => 30, 'five' => 50]
Метод dump
выводит элементы коллекции:
$collection = collect(['John Doe', 'Jane Doe']);
$collection->dump();
/*
Collection {
#items: array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
}
*/
Если вы хотите прекратить выполнение скрипта после вывода элементов коллекции, используйте вместо этого метод dd
.
Метод duplicates
извлекает и возвращает повторяющиеся значения из коллекции:
$collection = collect(['a', 'b', 'a', 'c', 'b']);
$collection->duplicates();
// [2 => 'a', 4 => 'b']
Если коллекция содержит массивы или объекты, вы можете передать ключ атрибутов, которые вы хотите проверить на наличие повторяющихся значений:
$employees = collect([
['email' => '[email protected]', 'position' => 'Developer'],
['email' => '[email protected]', 'position' => 'Designer'],
['email' => '[email protected]', 'position' => 'Developer'],
]);
$employees->duplicates('position');
// [2 => 'Developer']
Этот метод имеет ту же сигнатуру, что и метод duplicates
; однако, все значения сравниваются с использованием «жесткого» сравнения.
Метод each
перебирает элементы в коллекции и передает каждый элемент в замыкание:
$collection->each(function ($item, $key) {
//
});
Если вы хотите прекратить итерацию по элементам, вы можете вернуть false
из вашего замыкания:
$collection->each(function ($item, $key) {
if (/* condition */) {
return false;
}
});
Метод eachSpread
выполняет итерацию по элементам коллекции, передавая значение каждого вложенного элемента в замыкание:
$collection = collect([['John Doe', 35], ['Jane Doe', 33]]);
$collection->eachSpread(function ($name, $age) {
//
});
Если вы хотите прекратить итерацию по элементам, вы можете вернуть false
из вашего замыкания:
$collection->eachSpread(function ($name, $age) {
return false;
});
Метод every
используется для проверки того, что все элементы коллекции проходят указанный тест истинности:
collect([1, 2, 3, 4])->every(function ($value, $key) {
return $value > 2;
});
// false
Если коллекция пуста, метод every
вернет true
:
$collection = collect([]);
$collection->every(function ($value, $key) {
return $value > 2;
});
// true
Метод except
возвращает все элементы из коллекции, кроме тех, которые имеют указанные ключи:
$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);
$filtered = $collection->except(['price', 'discount']);
$filtered->all();
// ['product_id' => 1]
Противоположным методу except
является метод only.
{tip} Поведение этого метода изменяется при использовании коллекций Eloquent.
Метод filter
фильтрует коллекцию, используя переданное замыкание, сохраняя только те элементы, которые проходят указанный тест истинности:
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->filter(function ($value, $key) {
return $value > 2;
});
$filtered->all();
// [3, 4]
Если замыкание не указано, то все записи коллекции, эквивалентные false
, будут удалены:
$collection = collect([1, 2, 3, null, false, '', 0, []]);
$collection->filter()->all();
// [1, 2, 3]
Противоположным методу filter
является метод reject.
Метод first
возвращает первый элемент из коллекции, который проходит указанную проверку истинности:
collect([1, 2, 3, 4])->first(function ($value, $key) {
return $value > 2;
});
// 3
Вы также можете вызвать метод first
без аргументов, чтобы получить первый элемент из коллекции. Если коллекция пуста, возвращается null
:
collect([1, 2, 3, 4])->first();
// 1
Метод firstWhere
возвращает первый элемент коллекции с переданной парой ключ / значение:
$collection = collect([
['name' => 'Regena', 'age' => null],
['name' => 'Linda', 'age' => 14],
['name' => 'Diego', 'age' => 23],
['name' => 'Linda', 'age' => 84],
]);
$collection->firstWhere('name', 'Linda');
// ['name' => 'Linda', 'age' => 14]
Вы также можете вызвать метод firstWhere
с оператором сравнения:
$collection->firstWhere('age', '>=', 18);
// ['name' => 'Diego', 'age' => 23]
Подобно методу where, вы можете передать один аргумент методу firstWhere
. В этом сценарии метод firstWhere
вернет первый элемент, для которого значение данного ключа элемента является «истинным»:
$collection->firstWhere('age');
// ['name' => 'Linda', 'age' => 14]
Метод flatMap
выполняет итерацию по коллекции и передает каждое значение переданному замыканию. Замыкание может изменить элемент и вернуть его, таким образом формируя новую коллекцию измененных элементов. Затем массив преобразуется в плоскую структуру:
$collection = collect([
['name' => 'Sally'],
['school' => 'Arkansas'],
['age' => 28]
]);
$flattened = $collection->flatMap(function ($values) {
return array_map('strtoupper', $values);
});
$flattened->all();
// ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];
Метод flatten
объединяет многомерную коллекцию в одноуровневую:
$collection = collect([
'name' => 'taylor',
'languages' => [
'php', 'javascript'
]
]);
$flattened = $collection->flatten();
$flattened->all();
// ['taylor', 'php', 'javascript'];
Если необходимо, вы можете передать методу flatten
аргумент «глубины»:
$collection = collect([
'Apple' => [
[
'name' => 'iPhone 6S',
'brand' => 'Apple'
],
],
'Samsung' => [
[
'name' => 'Galaxy S7',
'brand' => 'Samsung'
],
],
]);
$products = $collection->flatten(1);
$products->values()->all();
/*
[
['name' => 'iPhone 6S', 'brand' => 'Apple'],
['name' => 'Galaxy S7', 'brand' => 'Samsung'],
]
*/
В этом примере вызов flatten
без указания глубины также привел бы к сглаживанию вложенных массивов, что привело бы к ['iPhone 6S', 'Apple', 'Galaxy S7', 'Samsung']
. Предоставление глубины позволяет указать количество уровней, на которые будут сглажены вложенные массивы.
Метод flip
меняет местами ключи коллекции на их соответствующие значения:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$flipped = $collection->flip();
$flipped->all();
// ['taylor' => 'name', 'laravel' => 'framework']
Метод forget
удаляет элемент из коллекции по его ключу:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$collection->forget('name');
$collection->all();
// ['framework' => 'laravel']
{note} В отличие от большинства других методов коллекции,
forget
модифицирует коллекцию.
Метод forPage
возвращает новую коллекцию, содержащую элементы, которые будут присутствовать на указанном номере страницы. Метод принимает номер страницы в качестве первого аргумента и количество элементов, отображаемых на странице, в качестве второго аргумента:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);
$chunk = $collection->forPage(2, 3);
$chunk->all();
// [4, 5, 6]
Метод get
возвращает элемент по указанному ключу. Если ключ не существует, возвращается null
:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$value = $collection->get('name');
// taylor
При желании вы можете передать значение по умолчанию в качестве второго аргумента:
$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);
$value = $collection->get('age', 34);
// 34
Вы даже можете передать замыкание как значение метода по умолчанию. Результат замыкания будет возвращен, если указанный ключ не существует:
$collection->get('email', function () {
return '[email protected]';
});
// [email protected]
Метод groupBy
группирует элементы коллекции по указанному ключу:
$collection = collect([
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
['account_id' => 'account-x11', 'product' => 'Desk'],
]);
$grouped = $collection->groupBy('account_id');
$grouped->all();
/*
[
'account-x10' => [
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
],
'account-x11' => [
['account_id' => 'account-x11', 'product' => 'Desk'],
],
]
*/
Вместо передачи строкового ключа вы можете передать замыкание. Замыкание должно вернуть значение, используемое в качестве ключа для группировки:
$grouped = $collection->groupBy(function ($item, $key) {
return substr($item['account_id'], -3);
});
$grouped->all();
/*
[
'x10' => [
['account_id' => 'account-x10', 'product' => 'Chair'],
['account_id' => 'account-x10', 'product' => 'Bookcase'],
],
'x11' => [
['account_id' => 'account-x11', 'product' => 'Desk'],
],
]
*/
В виде массива можно передать несколько критериев группировки. Каждый элемент массива будет применен к соответствующему уровню в многомерном массиве:
$data = new Collection([
10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],
40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],
]);
$result = $data->groupBy(['skill', function ($item) {
return $item['roles'];
}], $preserveKeys = true);
/*
[
1 => [
'Role_1' => [
10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
],
'Role_2' => [
20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
],
'Role_3' => [
10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
],
],
2 => [
'Role_1' => [
30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],
],
'Role_2' => [
40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],
],
],
];
*/
Метод has
определяет, существует ли переданный ключ в коллекции:
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);
$collection->has('product');
// true
$collection->has(['product', 'amount']);
// true
$collection->has(['amount', 'price']);
// false
Метод implode
объединяет элементы коллекции. Его аргументы зависят от типа элементов в коллекции. Если коллекция содержит массивы или объекты, вы должны передать ключ объединяемых атрибутов, и «связующую строку», размещаемую между значениями:
$collection = collect([
['account_id' => 1, 'product' => 'Desk'],
['account_id' => 2, 'product' => 'Chair'],
]);
$collection->implode('product', ', ');
// Desk, Chair
Если коллекция содержит простые строки или числовые значения, вы должны передать «связующую строку» как единственный аргумент методу:
collect([1, 2, 3, 4, 5])->implode('-');
// '1-2-3-4-5'
Метод intersect
удаляет любые значения из исходной коллекции, которых нет в указанном массиве или коллекции. Полученная коллекция сохранит ключи исходной коллекции:
$collection = collect(['Desk', 'Sofa', 'Chair']);
$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);
$intersect->all();
// [0 => 'Desk', 2 => 'Chair']
{tip} Поведение этого метода изменяется при использовании коллекций Eloquent.
Метод intersectByKeys
удаляет все ключи и соответствующие им значения из исходной коллекции, ключи которых отсутствуют в указанном массиве или коллекции:
$collection = collect([
'serial' => 'UX301', 'type' => 'screen', 'year' => 2009,
]);
$intersect = $collection->intersectByKeys([
'reference' => 'UX404', 'type' => 'tab', 'year' => 2011,
]);
$intersect->all();
// ['type' => 'screen', 'year' => 2009]
Метод isEmpty
возвращает true
, если коллекция пуста; в противном случае возвращается false
:
collect([])->isEmpty();
// true
Метод isNotEmpty
возвращает true
, если коллекция не пуста; в противном случае возвращается false
:
collect([])->isNotEmpty();
// false
Метод join
объединяет значения коллекции в строку. Используя второй аргумент этого метода, вы также можете указать, как последний элемент должен быть добавлен к строке:
collect(['a', 'b', 'c'])->join(', '); // 'a, b, c'
collect(['a', 'b', 'c'])->join(', ', ', and '); // 'a, b, and c'
collect(['a', 'b'])->join(', ', ' and '); // 'a and b'
collect(['a'])->join(', ', ' and '); // 'a'
collect([])->join(', ', ' and '); // ''
Метод keyBy
возвращает коллекцию, элементы которой будут образованы путем присвоения ключей элементам базовой коллекции. Если у нескольких элементов один и тот же ключ, в новой коллекции появится только последний:
$collection = collect([
['product_id' => 'prod-100', 'name' => 'Desk'],
['product_id' => 'prod-200', 'name' => 'Chair'],
]);
$keyed = $collection->keyBy('product_id');
$keyed->all();
/*
[
'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
]
*/
Вы также можете передать методу замыкание. Замыкание должно возвращать имя для ключа коллекции:
$keyed = $collection->keyBy(function ($item) {
return strtoupper($item['product_id']);
});
$keyed->all();
/*
[
'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
]
*/
Метод keys
возвращает все ключи коллекции:
$collection = collect([
'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
]);
$keys = $collection->keys();
$keys->all();
// ['prod-100', 'prod-200']
Метод last
возвращает последний элемент в коллекции, который проходит указанную проверку истинности:
collect([1, 2, 3, 4])->last(function ($value, $key) {
return $value < 3;
});
// 2
Вы также можете вызвать метод last
без аргументов, чтобы получить последний элемент коллекции. Если коллекция пуста, возвращается null
:
collect([1, 2, 3, 4])->last();
// 4
Статический метод macro
позволяет вам добавлять методы к классу Collection
во время выполнения. Обратитесь к документации по расширению коллекций для получения дополнительной информации.
Статический метод make
создает новый экземпляр коллекции. См. раздел Создание коллекций.
Метод map
выполняет итерацию по коллекции и передает каждое значение указанному замыканию. Замыкание может изменить элемент и вернуть его, образуя новую коллекцию измененных элементов:
$collection = collect([1, 2, 3, 4, 5]);
$multiplied = $collection->map(function ($item, $key) {
return $item * 2;
});
$multiplied->all();
// [2, 4, 6, 8, 10]
{note} Как и большинство других методов коллекции,
map
возвращает новый экземпляр коллекции; он не модифицирует коллекцию. Если вы хотите преобразовать исходную коллекцию, используйте методtransform
.
Метод mapInto()
выполняет итерацию коллекции, создавая новый экземпляр указанного класса, и передавая значение в его конструктор:
class Currency
{
/**
* Создать новый экземпляр валюты.
*
* @param string $code
* @return void
*/
function __construct(string $code)
{
$this->code = $code;
}
}
$collection = collect(['USD', 'EUR', 'GBP']);
$currencies = $collection->mapInto(Currency::class);
$currencies->all();
// [Currency('USD'), Currency('EUR'), Currency('GBP')]
Метод mapSpread
выполняет итерацию по элементам коллекции, передавая значение каждого вложенного элемента в указанное замыкание. Замыкание может изменить элемент и вернуть его, таким образом формируя новую коллекцию измененных элементов:
$collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
$chunks = $collection->chunk(2);
$sequence = $chunks->mapSpread(function ($even, $odd) {
return $even + $odd;
});
$sequence->all();
// [1, 5, 9, 13, 17]
Метод mapToGroups
группирует элементы коллекции по указанному замыканию. Замыкание должно возвращать ассоциативный массив, содержащий одну пару ключ / значение, таким образом формируя новую коллекцию сгруппированных значений:
$collection = collect([
[
'name' => 'John Doe',
'department' => 'Sales',
],
[
'name' => 'Jane Doe',
'department' => 'Sales',
],
[
'name' => 'Johnny Doe',
'department' => 'Marketing',
]
]);
$grouped = $collection->mapToGroups(function ($item, $key) {
return [$item['department'] => $item['name']];
});
$grouped->all();
/*
[
'Sales' => ['John Doe', 'Jane Doe'],
'Marketing' => ['Johnny Doe'],
]
*/
$grouped->get('Sales')->all();
// ['John Doe', 'Jane Doe']
Метод mapWithKeys
выполняет итерацию по коллекции и передает каждое значение в указанное замыкание. Замыкание должно возвращать ассоциативный массив, содержащий одну пару ключ / значение:
$collection = collect([
[
'name' => 'John',
'department' => 'Sales',
'email' => '[email protected]',
],
[
'name' => 'Jane',
'department' => 'Marketing',
'email' => '[email protected]',
]
]);
$keyed = $collection->mapWithKeys(function ($item, $key) {
return [$item['email'] => $item['name']];
});
$keyed->all();
/*
[
'[email protected]' => 'John',
'[email protected]' => 'Jane',
]
*/
Метод max
возвращает максимальное значение переданного ключа:
$max = collect([
['foo' => 10],
['foo' => 20]
])->max('foo');
// 20
$max = collect([1, 2, 3, 4, 5])->max();
// 5
Метод median
возвращает медиану переданного ключа:
$median = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->median('foo');
// 15
$median = collect([1, 1, 2, 4])->median();
// 1.5
Метод merge
объединяет переданный массив или коллекцию с исходной коллекцией. Если строковый ключ в переданных элементах соответствует строковому ключу в исходной коллекции, значение переданного элемента перезапишет значение в исходной коллекции:
$collection = collect(['product_id' => 1, 'price' => 100]);
$merged = $collection->merge(['price' => 200, 'discount' => false]);
$merged->all();
// ['product_id' => 1, 'price' => 200, 'discount' => false]
Если ключи переданных элементов являются числовыми, значения будут добавлены в конец коллекции:
$collection = collect(['Desk', 'Chair']);
$merged = $collection->merge(['Bookcase', 'Door']);
$merged->all();
// ['Desk', 'Chair', 'Bookcase', 'Door']
Метод mergeRecursive
рекурсивно объединяет переданный массив или коллекцию с исходной коллекцией. Если строковый ключ в переданных элементах совпадает со строковым ключом в исходной коллекции, тогда значения этих ключей объединяются в массив, и это делается рекурсивно:
$collection = collect(['product_id' => 1, 'price' => 100]);
$merged = $collection->mergeRecursive([
'product_id' => 2,
'price' => 200,
'discount' => false
]);
$merged->all();
// ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false]
Метод min
возвращает минимальное значение переданного ключа:
$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');
// 10
$min = collect([1, 2, 3, 4, 5])->min();
// 1
Метод mode
возвращает значение моды указанного ключа:
$mode = collect([
['foo' => 10],
['foo' => 10],
['foo' => 20],
['foo' => 40]
])->mode('foo');
// [10]
$mode = collect([1, 1, 2, 4])->mode();
// [1]
$mode = collect([1, 1, 2, 2])->mode();
// [1, 2]
Метод nth
создает новую коллекцию, состоящую из каждого n
-го элемента:
$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);
$collection->nth(4);
// ['a', 'e']
При желании вы можете передать начальное смещение в качестве второго аргумента:
$collection->nth(4, 1);
// ['b', 'f']
Метод only
возвращает элементы коллекции только с указанными ключами:
$collection = collect([
'product_id' => 1,
'name' => 'Desk',
'price' => 100,
'discount' => false
]);
$filtered = $collection->only(['product_id', 'name']);
$filtered->all();
// ['product_id' => 1, 'name' => 'Desk']
Противоположным методу only
является метод except.
{tip} Поведение этого метода изменяется при использовании коллекций Eloquent.
Метод pad
дополнит коллекцию определенным значением, пока коллекция не достигнет указанного размера. Этот метод ведет себя как функция array_pad PHP.
Для дополнения слева следует указать отрицательный размер. Если абсолютное значение указанного размера меньше или равно длине массива, заполнение не произойдет:
$collection = collect(['A', 'B', 'C']);
$filtered = $collection->pad(5, 0);
$filtered->all();
// ['A', 'B', 'C', 0, 0]
$filtered = $collection->pad(-5, 0);
$filtered->all();
// [0, 0, 'A', 'B', 'C']
Метод partition
может быть объединен с деструктуризацией массива PHP для разделения элементов, прошедших указанную проверку истинности, от тех, которые ее не прошли:
$collection = collect([1, 2, 3, 4, 5, 6]);
[$underThree, $equalOrAboveThree] = $collection->partition(function ($i) {
return $i < 3;
});
$underThree->all();
// [1, 2]
$equalOrAboveThree->all();
// [3, 4, 5, 6]
Метод pipe
передает коллекцию указанному замыканию и возвращает результат выполненного замыкания:
$collection = collect([1, 2, 3]);
$piped = $collection->pipe(function ($collection) {
return $collection->sum();
});
// 6
Метод pipeInto
создает новый экземпляр указанного класса и передает коллекцию в конструктор:
class ResourceCollection
{
/**
* Экземпляр Collection.
*/
public $collection;
/**
* Создать новый экземпляр ResourceCollection.
*
* @param Collection $collection
* @return void
*/
public function __construct(Collection $collection)
{
$this->collection = $collection;
}
}
$collection = collect([1, 2, 3]);
$resource = $collection->pipeInto(ResourceCollection::class);
$resource->collection->all();
// [1, 2, 3]
Метод pluck
извлекает все значения для указанного ключа:
$collection = collect([
['product_id' => 'prod-100', 'name' => 'Desk'],
['product_id' => 'prod-200', 'name' => 'Chair'],
]);
$plucked = $collection->pluck('name');
$plucked->all();
// ['Desk', 'Chair']
Вы также можете задать ключ результирующей коллекции:
$plucked = $collection->pluck('name', 'product_id');
$plucked->all();
// ['prod-100' => 'Desk', 'prod-200' => 'Chair']
Метод pluck
также поддерживает получение вложенных значений с использованием «точечной нотации»:
$collection = collect([
[
'speakers' => [
'first_day' => ['Rosa', 'Judith'],
'second_day' => ['Angela', 'Kathleen'],
],
],
]);
$plucked = $collection->pluck('speakers.first_day');
$plucked->all();
// ['Rosa', 'Judith']
Если существуют повторяющиеся ключи, последний соответствующий элемент будет вставлен в результирующую коллекцию:
$collection = collect([
['brand' => 'Tesla', 'color' => 'red'],
['brand' => 'Pagani', 'color' => 'white'],
['brand' => 'Tesla', 'color' => 'black'],
['brand' => 'Pagani', 'color' => 'orange'],
]);
$plucked = $collection->pluck('color', 'brand');
$plucked->all();
// ['Tesla' => 'black', 'Pagani' => 'orange']
Метод pop
удаляет и возвращает последний элемент из коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$collection->pop();
// 5
$collection->all();
// [1, 2, 3, 4]
Вы можете передать целое число методу pop
, чтобы удалить (с возвратом) несколько элементов из конца коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$collection->pop(3);
// collect([5, 4, 3])
$collection->all();
// [1, 2]
Метод prepend
добавляет элемент в начало коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$collection->prepend(0);
$collection->all();
// [0, 1, 2, 3, 4, 5]
Вы также можете передать второй аргумент, чтобы указать ключ добавляемого элемента:
$collection = collect(['one' => 1, 'two' => 2]);
$collection->prepend(0, 'zero');
$collection->all();
// ['zero' => 0, 'one' => 1, 'two' => 2]
Метод pull
удаляет и возвращает элемент из коллекции по его ключу:
$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);
$collection->pull('name');
// 'Desk'
$collection->all();
// ['product_id' => 'prod-100']
Метод push
добавляет элемент в конец коллекции:
$collection = collect([1, 2, 3, 4]);
$collection->push(5);
$collection->all();
// [1, 2, 3, 4, 5]
Метод put
помещает указанные ключ и значение в коллекцию:
$collection = collect(['product_id' => 1, 'name' => 'Desk']);
$collection->put('price', 100);
$collection->all();
// ['product_id' => 1, 'name' => 'Desk', 'price' => 100]
Метод random
возвращает случайный элемент из коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$collection->random();
// 4 - (retrieved randomly)
Вы можете передать целое число в random
, чтобы указать, сколько случайных элементов вы хотите получить. Коллекция элементов всегда возвращается при явной передаче количества элементов, которые вы хотите получить:
$random = $collection->random(3);
$random->all();
// [2, 4, 5] - (retrieved randomly)
Если в экземпляре коллекции меньше элементов, чем запрошено, метод random
сгенерирует исключение InvalidArgumentException
.
Метод reduce
сокращает коллекцию до одного значения, передавая результат каждой итерации следующей итерации:
$collection = collect([1, 2, 3]);
$total = $collection->reduce(function ($carry, $item) {
return $carry + $item;
});
// 6
Значение $carry
первой итерации равно null
; однако вы можете указать его начальное значение, передав второй аргумент методу reduce
:
$collection->reduce(function ($carry, $item) {
return $carry + $item;
}, 4);
// 10
Метод reduce
также передает ключи массива ассоциативных коллекций указанному замыканию:
$collection = collect([
'usd' => 1400,
'gbp' => 1200,
'eur' => 1000,
]);
$ratio = [
'usd' => 1,
'gbp' => 1.37,
'eur' => 1.22,
];
$collection->reduce(function ($carry, $value, $key) use ($ratio) {
return $carry + ($value * $ratio[$key]);
});
// 4264
Метод reject
фильтрует коллекцию, используя переданное замыкание. Замыкание должно возвращать true
, если элемент должен быть удален из результирующей коллекции:
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->reject(function ($value, $key) {
return $value > 2;
});
$filtered->all();
// [1, 2]
Противоположным методу reject
является метод filter
.
Метод replace
ведет себя аналогично методу merge
; однако, помимо перезаписи совпадающих элементов, имеющих строковые ключи, метод replace
также перезаписывает элементы в коллекции, у которых есть совпадающие числовые ключи:
$collection = collect(['Taylor', 'Abigail', 'James']);
$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);
$replaced->all();
// ['Taylor', 'Victoria', 'James', 'Finn']
Этот метод работает как и replace
, но он будет повторяться в массивах и применять тот же процесс замены к внутренним значениям:
$collection = collect([
'Taylor',
'Abigail',
[
'James',
'Victoria',
'Finn'
]
]);
$replaced = $collection->replaceRecursive([
'Charlie',
2 => [1 => 'King']
]);
$replaced->all();
// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]
Метод reverse
меняет порядок элементов коллекции на обратный, сохраняя исходные ключи:
$collection = collect(['a', 'b', 'c', 'd', 'e']);
$reversed = $collection->reverse();
$reversed->all();
/*
[
4 => 'e',
3 => 'd',
2 => 'c',
1 => 'b',
0 => 'a',
]
*/
Метод search
ищет в коллекции указанное значение и возвращает его ключ, если он найден. Если элемент не найден, возвращается false
:
$collection = collect([2, 4, 6, 8]);
$collection->search(4);
// 1
Поиск выполняется с использованием «гибкого» сравнения, то есть строка с целым значением будет считаться равной целому числу того же значения. Чтобы использовать «жесткое» сравнение, передайте true
в качестве второго аргумента метода:
collect([2, 4, 6, 8])->search('4', $strict = true);
// false
В качестве альтернативы вы можете передать собственное замыкание для поиска первого элемента, который проходит указанный тест на истинность:
collect([2, 4, 6, 8])->search(function ($item, $key) {
return $item > 5;
});
// 2
Метод shift
удаляет и возвращает первый элемент из коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$collection->shift();
// 1
$collection->all();
// [2, 3, 4, 5]
Вы можете передать целое число методу shift
, чтобы удалить (с возвратом) несколько элементов из начала коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$collection->shift(3);
// collect([1, 2, 3])
$collection->all();
// [4, 5]
Метод shuffle
случайным образом перемешивает элементы в коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$shuffled = $collection->shuffle();
$shuffled->all();
// [3, 2, 5, 1, 4] - (generated randomly)
Метод sliding
возвращает новую фрагментированную коллекцию, представляющих вид «скользящего окна» элементов:
$collection = collect([1, 2, 3, 4, 5]);
$chunks = $collection->sliding(2);
$chunks->toArray();
// [[1, 2], [2, 3], [3, 4], [4, 5]]
Это особенно полезно в сочетании с методом eachSpread
:
$transactions->sliding(2)->eachSpread(function ($previous, $current) {
$current->total = $previous->total + $current->amount;
});
При желании вы можете передать второе значение step
, которое определяет расстояние между первым элементом каждого фрагмента:
$collection = collect([1, 2, 3, 4, 5]);
$chunks = $collection->sliding(3, step: 2);
$chunks->toArray();
// [[1, 2, 3], [3, 4, 5]]
Метод skip
возвращает новую коллекцию с указанным количеством удаляемых из начала коллекции элементов:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$collection = $collection->skip(4);
$collection->all();
// [5, 6, 7, 8, 9, 10]
Метод skipUntil
пропускает элементы из коллекции до тех пор, пока переданное замыкание не вернет true
, а затем вернет оставшиеся элементы в коллекции как новый экземпляр коллекции:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipUntil(function ($item) {
return $item >= 3;
});
$subset->all();
// [3, 4]
Вы также можете передать простое значение методу skipUntil
, чтобы пропустить все элементы, пока не будет найдено указанное значение:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipUntil(3);
$subset->all();
// [3, 4]
{note} Если указанное значение не найдено или замыкание никогда не возвращает
true
, то методskipUntil
вернет пустую коллекцию.
Метод skipWhile
пропускает элементы из коллекции, пока указанное замыкание возвращает true
, а затем возвращает оставшиеся элементы в коллекции как новую коллекцию:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipWhile(function ($item) {
return $item <= 3;
});
$subset->all();
// [4]
{note} Если замыкание никогда не возвращает
true
, то методskipWhile
вернет пустую коллекцию.
Метод slice
возвращает фрагмент коллекции, начиная с указанного индекса:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$slice = $collection->slice(4);
$slice->all();
// [5, 6, 7, 8, 9, 10]
Если вы хотите ограничить размер возвращаемого фрагмента, то передайте желаемый размер в качестве второго аргумента метода:
$slice = $collection->slice(4, 2);
$slice->all();
// [5, 6]
Возвращенный фрагмент по умолчанию сохранит ключи. Если вы не хотите сохранять исходные ключи, вы можете использовать метод values
, чтобы переиндексировать их.
Метод sole
возвращает первый элемент, который является единственным элементом в коллекции, прошедшим указанный тест истинности:
collect([1, 2, 3, 4])->sole(function ($value, $key) {
return $value === 2;
});
// 2
Вы также можете передать пару ключ / значение методу sole
, который вернет первый и единственный элемент коллекции, соответствующий переданной паре:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
]);
$collection->sole('product', 'Chair');
// ['product' => 'Chair', 'price' => 100]
В качестве альтернативы вы также можете вызвать метод sole
без аргументов, чтобы получить первый элемент, который является единственным элементом в коллекции:
$collection = collect([
['product' => 'Desk', 'price' => 200],
]);
$collection->sole();
// ['product' => 'Desk', 'price' => 200]
Если в коллекции нет элементов, которые должны быть возвращены методом sole
, то будет выброшено исключение \Illuminate\Collections\ItemNotFoundException
. Если таких элементов в коллекции более одного элемента, то будет выброшено исключение \Illuminate\Collections\MultipleItemsFoundException
.
Псевдоним для метода contains
.
Метод sort
сортирует коллекцию. В отсортированной коллекции хранятся исходные ключи массива, поэтому в следующем примере мы будем использовать метод values
для сброса ключей для последовательной нумерации индексов:
$collection = collect([5, 3, 1, 2, 4]);
$sorted = $collection->sort();
$sorted->values()->all();
// [1, 2, 3, 4, 5]
Если ваши потребности в сортировке более сложны, вы можете передать замыкание методу sort
с вашим собственным алгоритмом. Обратитесь к документации PHP по uasort
, который используется внутри метода sort
.
{tip} Если вам нужно отсортировать коллекцию вложенных массивов или объектов, то см. методы
sortBy
иsortByDesc
.
Метод sortBy
сортирует коллекцию по указанному ключу. В отсортированной коллекции хранятся исходные ключи массива, поэтому в следующем примере мы будем использовать метод values
для сброса ключей для последовательной нумерации индексов:
$collection = collect([
['name' => 'Desk', 'price' => 200],
['name' => 'Chair', 'price' => 100],
['name' => 'Bookcase', 'price' => 150],
]);
$sorted = $collection->sortBy('price');
$sorted->values()->all();
/*
[
['name' => 'Chair', 'price' => 100],
['name' => 'Bookcase', 'price' => 150],
['name' => 'Desk', 'price' => 200],
]
*/
Метод sort
принимает флаги типа сортировки в качестве второго аргумента:
$collection = collect([
['title' => 'Item 1'],
['title' => 'Item 12'],
['title' => 'Item 3'],
]);
$sorted = $collection->sortBy('title', SORT_NATURAL);
$sorted->values()->all();
/*
[
['title' => 'Item 1'],
['title' => 'Item 3'],
['title' => 'Item 12'],
]
*/
В качестве альтернативы вы можете передать собственное замыкание, чтобы определить, как сортировать значения коллекции:
$collection = collect([
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]);
$sorted = $collection->sortBy(function ($product, $key) {
return count($product['colors']);
});
$sorted->values()->all();
/*
[
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]
*/
Если вы хотите отсортировать свою коллекцию по нескольким атрибутам, вы можете передать массив операций сортировки методу sortBy
. Каждая операция сортировки должна быть массивом, состоящим из атрибута, по которому вы хотите сортировать, и направления желаемой сортировки:
$collection = collect([
['name' => 'Taylor Otwell', 'age' => 34],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Abigail Otwell', 'age' => 32],
]);
$sorted = $collection->sortBy([
['name', 'asc'],
['age', 'desc'],
]);
$sorted->values()->all();
/*
[
['name' => 'Abigail Otwell', 'age' => 32],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Taylor Otwell', 'age' => 34],
]
*/
При сортировке коллекции по нескольким атрибутам вы также можете указать замыкания, определяющие каждую операцию сортировки:
$collection = collect([
['name' => 'Taylor Otwell', 'age' => 34],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Abigail Otwell', 'age' => 32],
]);
$sorted = $collection->sortBy([
fn ($a, $b) => $a['name'] <=> $b['name'],
fn ($a, $b) => $b['age'] <=> $a['age'],
]);
$sorted->values()->all();
/*
[
['name' => 'Abigail Otwell', 'age' => 32],
['name' => 'Abigail Otwell', 'age' => 30],
['name' => 'Taylor Otwell', 'age' => 36],
['name' => 'Taylor Otwell', 'age' => 34],
]
*/
Этот метод имеет ту же сигнатуру, что и метод sortBy
, но отсортирует коллекцию в обратном порядке.
Этот метод сортирует коллекцию в порядке, обратном методу sort
:
$collection = collect([5, 3, 1, 2, 4]);
$sorted = $collection->sortDesc();
$sorted->values()->all();
// [5, 4, 3, 2, 1]
В отличие от sort
, вы не можете передавать замыкание в sortDesc
. Вместо этого вы должны использовать метод sort
и инвертировать ваше сравнение.
Метод sortKeys
сортирует коллекцию по ключам базового ассоциативного массива:
$collection = collect([
'id' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
$sorted = $collection->sortKeys();
$sorted->all();
/*
[
'first' => 'John',
'id' => 22345,
'last' => 'Doe',
]
*/
Этот метод имеет ту же сигнатуру, что и метод sortKeys
, но отсортирует коллекцию в обратном порядке.
Метод splice
удаляет и возвращает фрагмент элементов, начиная с указанного индекса:
$collection = collect([1, 2, 3, 4, 5]);
$chunk = $collection->splice(2);
$chunk->all();
// [3, 4, 5]
$collection->all();
// [1, 2]
Вы можете передать второй аргумент, чтобы ограничить размер результирующей коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$chunk = $collection->splice(2, 1);
$chunk->all();
// [3]
$collection->all();
// [1, 2, 4, 5]
Кроме того, вы можете передать третий аргумент, содержащий новые элементы, чтобы заменить элементы, удаленные из коллекции:
$collection = collect([1, 2, 3, 4, 5]);
$chunk = $collection->splice(2, 1, [10, 11]);
$chunk->all();
// [3]
$collection->all();
// [1, 2, 10, 11, 4, 5]
Метод split
разбивает коллекцию на указанное количество групп:
$collection = collect([1, 2, 3, 4, 5]);
$groups = $collection->split(3);
$groups->all();
// [[1, 2], [3, 4], [5]]
Метод splitIn
разбивает коллекцию на указанное количество групп, полностью заполняя нетерминальные группы перед тем, как выделить остаток последней группе:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
$groups = $collection->splitIn(3);
$groups->all();
// [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
Метод sum
возвращает сумму всех элементов в коллекции:
collect([1, 2, 3, 4, 5])->sum();
// 15
Если коллекция содержит вложенные массивы или объекты, вы должны передать ключ, который будет использоваться для определения суммирования значений:
$collection = collect([
['name' => 'JavaScript: The Good Parts', 'pages' => 176],
['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],
]);
$collection->sum('pages');
// 1272
Кроме того, вы можете передать собственное замыкание, чтобы определить, какие значения коллекции суммировать:
$collection = collect([
['name' => 'Chair', 'colors' => ['Black']],
['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]);
$collection->sum(function ($product) {
return count($product['colors']);
});
// 6
Метод take
возвращает новую коллекцию с указанным количеством элементов:
$collection = collect([0, 1, 2, 3, 4, 5]);
$chunk = $collection->take(3);
$chunk->all();
// [0, 1, 2]
Вы также можете передать отрицательное целое число, чтобы получить указанное количество элементов из конца коллекции:
$collection = collect([0, 1, 2, 3, 4, 5]);
$chunk = $collection->take(-2);
$chunk->all();
// [4, 5]
Метод takeUntil
возвращает элементы коллекции, пока указанное замыкание не вернет true
:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeUntil(function ($item) {
return $item >= 3;
});
$subset->all();
// [1, 2]
Вы также можете передать простое значение методу takeUntil
, чтобы получать элементы, пока не будет найдено указанное значение:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeUntil(3);
$subset->all();
// [1, 2]
{note} Если указанное значение не найдено или замыкание никогда не возвращает
true
, то методtakeUntil
вернет все элементы коллекции.
Метод takeWhile
возвращает элементы коллекции до тех пор, пока указанное замыкание не вернет false
:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeWhile(function ($item) {
return $item < 3;
});
$subset->all();
// [1, 2]
{note} Если замыкание никогда не возвращает
false
, методtakeWhile
вернет все элементы коллекции.
Метод tap
передает коллекцию указанному замыканию, позволяя вам «перехватить» коллекцию в определенный момент и сделать что-то с элементами, не затрагивая саму коллекцию. Затем коллекция возвращается методом tap
:
collect([2, 4, 3, 1, 5])
->sort()
->tap(function ($collection) {
Log::debug('Values after sorting', $collection->values()->all());
})
->shift();
// 1
Статический метод times
создает новую коллекцию, вызывая переданное замыкание указанное количество раз:
$collection = Collection::times(10, function ($number) {
return $number * 9;
});
$collection->all();
// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
Метод toArray
преобразует коллекцию в простой массив PHP. Если значениями коллекции являются модели Eloquent, то модели также будут преобразованы в массивы:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toArray();
/*
[
['name' => 'Desk', 'price' => 200],
]
*/
{note} Метод
toArray
также преобразует все вложенные объекты коллекции, которые являются экземпляромArrayable
, в массив. Если вы хотите получить необработанный массив, лежащий в основе коллекции, используйте вместо этого методall
.
Метод toJson
преобразует коллекцию в сериализованную строку JSON:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toJson();
// '{"name":"Desk", "price":200}'
Метод transform
выполняет итерацию коллекции и вызывает указанное замыкание для каждого элемента в коллекции. Элементы в коллекции будут заменены значениями, возвращаемыми замыканием:
$collection = collect([1, 2, 3, 4, 5]);
$collection->transform(function ($item, $key) {
return $item * 2;
});
$collection->all();
// [2, 4, 6, 8, 10]
{note} В отличие от большинства других методов коллекции,
transform
модифицирует коллекцию. Если вы хотите вместо этого создать новую коллекцию, используйте методmap
.
Метод union
добавляет переданный массив в коллекцию. Если переданный массив содержит ключи, которые уже находятся в исходной коллекции, предпочтительнее будут значения исходной коллекции:
$collection = collect([1 => ['a'], 2 => ['b']]);
$union = $collection->union([3 => ['c'], 1 => ['d']]);
$union->all();
// [1 => ['a'], 2 => ['b'], 3 => ['c']]
Метод unique
возвращает все уникальные элементы коллекции. Возвращенная коллекция сохраняет исходные ключи массива, поэтому в следующем примере мы будем использовать метод values
для сброса ключей для последовательной нумерации индексов:
$collection = collect([1, 1, 2, 2, 3, 4, 2]);
$unique = $collection->unique();
$unique->values()->all();
// [1, 2, 3, 4]
При работе с вложенными массивами или объектами вы можете указать ключ, используемый для определения уникальности:
$collection = collect([
['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],
['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],
]);
$unique = $collection->unique('brand');
$unique->values()->all();
/*
[
['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
]
*/
Наконец, вы также можете передать собственное замыкание методу unique
, чтобы указать, какое значение должно определять уникальность элемента:
$unique = $collection->unique(function ($item) {
return $item['brand'].$item['type'];
});
$unique->values()->all();
/*
[
['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],
['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],
]
*/
Метод unique
использует «гибкое» сравнение при проверке значений элементов, то есть строка с целым значением будет считаться равной целому числу того же значения. Используйте метод uniqueStrict
для фильтрации с использованием «жесткого» сравнения.
{tip} Поведение этого метода изменяется при использовании коллекций Eloquent.
Этот метод имеет ту же сигнатуру, что и метод unique
; однако, все значения сравниваются с использованием «жесткого» сравнения.
Метод unless
выполнит указанное замыкание, если первый аргумент, переданный методу, не будет иметь значение true
:
$collection = collect([1, 2, 3]);
$collection->unless(true, function ($collection) {
return $collection->push(4);
});
$collection->unless(false, function ($collection) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]
Противоположным методу unless
является метод when
.
Псевдоним для метода whenNotEmpty
.
Псевдоним для метода whenEmpty
.
Статический метод unwrap
возвращает базовые элементы коллекции из указанного значения, когда это применимо:
Collection::unwrap(collect('John Doe'));
// ['John Doe']
Collection::unwrap(['John Doe']);
// ['John Doe']
Collection::unwrap('John Doe');
// 'John Doe'
Метод values
возвращает новую коллекцию с ключами, сброшенными на последовательные целые числа:
$collection = collect([
10 => ['product' => 'Desk', 'price' => 200],
11 => ['product' => 'Desk', 'price' => 200],
]);
$values = $collection->values();
$values->all();
/*
[
0 => ['product' => 'Desk', 'price' => 200],
1 => ['product' => 'Desk', 'price' => 200],
]
*/
Метод when
выполнит указанное замыкание, когда первый аргумент, переданный методу, оценивается как true
:
$collection = collect([1, 2, 3]);
$collection->when(true, function ($collection) {
return $collection->push(4);
});
$collection->when(false, function ($collection) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 4]
Противоположным методу when
является метод unless
.
Метод whenEmpty
выполнит указанное замыкание, когда коллекция пуста:
$collection = collect(['Michael', 'Tom']);
$collection->whenEmpty(function ($collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Michael', 'Tom']
$collection = collect();
$collection->whenEmpty(function ($collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Adam']
Второе замыкание может быть передано методу whenEmpty
, которое будет выполняться, если коллекция не пуста:
$collection = collect(['Michael', 'Tom']);
$collection->whenEmpty(function ($collection) {
return $collection->push('Adam');
}, function ($collection) {
return $collection->push('Taylor');
});
$collection->all();
// ['Michael', 'Tom', 'Taylor']
Противоположным методу whenEmpty
является метод whenNotEmpty
.
Метод whenNotEmpty
выполнит указанное замыкание, если коллекция не пуста:
$collection = collect(['michael', 'tom']);
$collection->whenNotEmpty(function ($collection) {
return $collection->push('adam');
});
$collection->all();
// ['michael', 'tom', 'adam']
$collection = collect();
$collection->whenNotEmpty(function ($collection) {
return $collection->push('adam');
});
$collection->all();
// []
Второе замыкание может быть передано методу whenNotEmpty
, которое будет выполняться, если коллекция пуста:
$collection = collect();
$collection->whenNotEmpty(function ($collection) {
return $collection->push('adam');
}, function ($collection) {
return $collection->push('taylor');
});
$collection->all();
// ['taylor']
Противоположным методу whenNotEmpty
является метод whenEmpty
.
Метод where
фильтрует коллекцию по указанной паре ключ / значение:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->where('price', 100);
$filtered->all();
/*
[
['product' => 'Chair', 'price' => 100],
['product' => 'Door', 'price' => 100],
]
*/
Метод where
использует «гибкое» сравнение при проверке значений элементов, что означает, что строка с целым значением будет считаться равной целому числу того же значения. Используйте метод whereStrict
для фильтрации с использованием «жесткого» сравнения.
При желании вы можете передать оператор сравнения в качестве второго параметра.
$collection = collect([
['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],
['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],
['name' => 'Sue', 'deleted_at' => null],
]);
$filtered = $collection->where('deleted_at', '!=', null);
$filtered->all();
/*
[
['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],
['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],
]
*/
Этот метод имеет ту же сигнатуру, что и метод where
; однако, все значения сравниваются с использованием «жесткого» сравнения.
Метод whereBetween
фильтрует коллекцию, определяя, находится ли переданное значение элемента в указанном диапазоне:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 80],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Pencil', 'price' => 30],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->whereBetween('price', [100, 200]);
$filtered->all();
/*
[
['product' => 'Desk', 'price' => 200],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]
*/
Метод whereIn
удаляет элементы из коллекции, у которых значения отсутствуют в указанном массиве:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->whereIn('price', [150, 200]);
$filtered->all();
/*
[
['product' => 'Desk', 'price' => 200],
['product' => 'Bookcase', 'price' => 150],
]
*/
Метод whereIn
использует «гибкое» сравнение при проверке значений элементов, что означает, что строка с целым значением будет считаться равной целому числу того же значения. Используйте метод whereInStrict
для фильтрации с использованием «жесткого» сравнения.
Этот метод имеет ту же сигнатуру, что и метод whereIn
; однако, все значения сравниваются с использованием «жесткого» сравнения.
Метод whereInstanceOf
фильтрует коллекцию по указанному типу класса:
use App\Models\User;
use App\Models\Post;
$collection = collect([
new User,
new User,
new Post,
]);
$filtered = $collection->whereInstanceOf(User::class);
$filtered->all();
// [App\Models\User, App\Models\User]
Метод whereNotBetween
фильтрует коллекцию, определяя, находится ли переданное значение элемента вне указанного диапазона:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 80],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Pencil', 'price' => 30],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->whereNotBetween('price', [100, 200]);
$filtered->all();
/*
[
['product' => 'Chair', 'price' => 80],
['product' => 'Pencil', 'price' => 30],
]
*/
Метод whereNotIn
удаляет элементы из коллекции, у которых значения присутствуют в указанном массиве:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]);
$filtered = $collection->whereNotIn('price', [150, 200]);
$filtered->all();
/*
[
['product' => 'Chair', 'price' => 100],
['product' => 'Door', 'price' => 100],
]
*/
Метод whereNotIn
использует «гибкое» сравнение при проверке значений элементов, что означает, что строка с целым значением будет считаться равной целому числу того же значения. Используйте метод whereNotInStrict
для фильтрации с использованием «жесткого» сравнения.
Этот метод имеет ту же сигнатуру, что и метод whereNotIn
; однако, все значения сравниваются с использованием «жесткого» сравнения.
Метод whereNotNull
возвращает элементы из коллекции, для которых значение указанного ключа не равно null
:
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
]);
$filtered = $collection->whereNotNull('name');
$filtered->all();
/*
[
['name' => 'Desk'],
['name' => 'Bookcase'],
]
*/
Метод whereNull
возвращает элементы из коллекции, для которых значение указанного ключа равно null
:
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
]);
$filtered = $collection->whereNull('name');
$filtered->all();
/*
[
['name' => null],
]
*/
Статический метод wrap
оборачивает указанное значение в коллекцию, если это применимо:
use Illuminate\Support\Collection;
$collection = Collection::wrap('John Doe');
$collection->all();
// ['John Doe']
$collection = Collection::wrap(['John Doe']);
$collection->all();
// ['John Doe']
$collection = Collection::wrap(collect('John Doe'));
$collection->all();
// ['John Doe']
Метод zip
объединяет значения переданного массива со значениями исходной коллекции по их соответствующему индексу:
$collection = collect(['Chair', 'Desk']);
$zipped = $collection->zip([100, 200]);
$zipped->all();
// [['Chair', 100], ['Desk', 200]]
Коллекции также обеспечивают поддержку «сообщений высшего порядка», которые являются сокращениями для выполнения общих действий с коллекциями. Методы коллекции, которые предоставляют сообщения высшего порядка: average
, avg
, contains
, each
, every
, filter
, first
, flatMap
, groupBy
, keyBy
, map
, max
, min
, partition
, reject
, skipUntil
, skipWhile
, some
, sortBy
, sortByDesc
, sum
, takeUntil
, takeWhile
, и unique
.
К каждому сообщению высшего порядка можно получить доступ как к динамическому свойству экземпляра коллекции. Например, давайте использовать сообщение высшего порядка each
, вызывая метод для каждого объекта коллекции:
use App\Models\User;
$users = User::where('votes', '>', 500)->get();
$users->each->markAsVip();
Точно так же мы можем использовать сообщение высшего порядка sum
, чтобы собрать общее количество «голосов» для коллекции пользователей:
$users = User::where('group', 'Development')->get();
return $users->sum->votes;
{note} Прежде чем узнать больше об отложенных коллекциях Laravel, потратьте некоторое время на то, чтобы ознакомиться с генераторами PHP.
В дополнении к мощному классу Collection
, класс LazyCollection
использует генераторы PHP, чтобы вы могли работать с очень большим наборы данных при низком потреблении памяти.
Например, представьте, что ваше приложение должно обрабатывать файл журнала размером в несколько гигабайт, используя при этом методы коллекций Laravel для анализа журналов. Вместо одновременного чтения всего файла в память можно использовать отложенные коллекции, чтобы сохранить в памяти только небольшую часть файла в текущий момент:
use App\Models\LogEntry;
use Illuminate\Support\LazyCollection;
LazyCollection::make(function () {
$handle = fopen('log.txt', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
})->chunk(4)->map(function ($lines) {
return LogEntry::fromLines($lines);
})->each(function (LogEntry $logEntry) {
// Process the log entry...
});
Или представьте, что вам нужно перебрать 10 000 моделей Eloquent. При использовании традиционных коллекций Laravel все 10 000 моделей Eloquent должны быть загружены в память одновременно:
use App\Models\User;
$users = User::all()->filter(function ($user) {
return $user->id > 500;
});
Однако, метод cursor
построителя запросов возвращает экземпляр LazyCollection
. Это позволяет вам по-прежнему выполнять только один запрос к базе данных, но при этом одновременно загружать в память только одну модель Eloquent. В этом примере замыкание метода filter
не выполнится до тех пор, пока мы на самом деле не переберем каждого пользователя индивидуально, что позволяет значительно сократить использование памяти:
use App\Models\User;
$users = User::cursor()->filter(function ($user) {
return $user->id > 500;
});
foreach ($users as $user) {
echo $user->id;
}
Чтобы создать экземпляр отложенной коллекции, вы должны передать функцию генератора PHP методу make
коллекции:
use Illuminate\Support\LazyCollection;
LazyCollection::make(function () {
$handle = fopen('log.txt', 'r');
while (($line = fgets($handle)) !== false) {
yield $line;
}
});
Почти все методы, доступные в классе Collection
, также доступны в классе LazyCollection
. Оба эти класса реализуют контракт Illuminate\Support\Enumerable
, который определяет следующие методы:
- all
- average
- avg
- chunk
- chunkWhile
- collapse
- collect
- combine
- concat
- contains
- containsStrict
- count
- countBy
- crossJoin
- dd
- diff
- diffAssoc
- diffKeys
- dump
- duplicates
- duplicatesStrict
- each
- eachSpread
- every
- except
- filter
- first
- firstWhere
- flatMap
- flatten
- flip
- forPage
- get
- groupBy
- has
- implode
- intersect
- intersectByKeys
- isEmpty
- isNotEmpty
- join
- keyBy
- keys
- last
- macro
- make
- map
- mapInto
- mapSpread
- mapToGroups
- mapWithKeys
- max
- median
- merge
- mergeRecursive
- min
- mode
- nth
- only
- pad
- partition
- pipe
- pluck
- random
- reduce
- reject
- replace
- replaceRecursive
- reverse
- search
- shuffle
- skip
- slice
- some
- sort
- sortBy
- sortByDesc
- sortKeys
- sortKeysDesc
- split
- sum
- take
- tap
- times
- toArray
- toJson
- union
- unique
- uniqueStrict
- unless
- unlessEmpty
- unlessNotEmpty
- unwrap
- values
- when
- whenEmpty
- whenNotEmpty
- where
- whereStrict
- whereBetween
- whereIn
- whereInStrict
- whereInstanceOf
- whereNotBetween
- whereNotIn
- whereNotInStrict
- wrap
- zip
{note} Методы, которые изменяют коллекцию (такие как
shift
,pop
,prepend
и т.д.), недоступны в классеLazyCollection
.
В дополнение к методам, определенным в контракте Enumerable
, класс LazyCollection
содержит следующие методы:
Метод takeUntilTimeout
возвращает новую отложенную коллекцию, которая будет перечислять значения до указанного времени. По истечении этого времени коллекция перестанет перечислять:
$lazyCollection = LazyCollection::times(INF)
->takeUntilTimeout(now()->addMinute());
$lazyCollection->each(function ($number) {
dump($number);
sleep(1);
});
// 1
// 2
// ...
// 58
// 59
Чтобы проиллюстрировать использование этого метода, представьте приложение, которое отправляет счета из базы данных с помощью курсора. Вы можете определить запланированную задачу, которая запускается каждые 15 минут и обрабатывает счета максимум 14 минут:
use App\Models\Invoice;
use Illuminate\Support\Carbon;
Invoice::pending()->cursor()
->takeUntilTimeout(
Carbon::createFromTimestamp(LARAVEL_START)->add(14, 'minutes')
)
->each(fn ($invoice) => $invoice->submit());
В то время как метод each
вызывает переданное замыкание для каждого элемента в коллекции сразу же, метод tapEach
вызывает переданное замыкание только тогда, когда элементы извлекаются из списка один за другим:
// Пока ничего не выведено ...
$lazyCollection = LazyCollection::times(INF)->tapEach(function ($value) {
dump($value);
});
// Три элемента выведено ...
$array = $lazyCollection->take(3)->all();
// 1
// 2
// 3
Метод remember
возвращает новую отложенную коллекцию, которая запоминает любые значения, которые уже были перечислены, и не будет извлекать их снова при последующих перечислениях коллекции:
// Запрос еще не выполнен ...
$users = User::cursor()->remember();
// Запрос выполнен ...
// Первые 5 пользователей из базы данных включены в результирующий набор ...
$users->take(5)->all();
// Первые 5 пользователей пришли из кеша коллекции ...
// Остальные из базы данных включены в результирующий набор ...
$users->take(20)->all();