Версия фреймворка:
5.4 4.2
Прогресс перевода
Перевод полностью актуален оригиналу.

Коллекции

Введение

Класс Illuminate\Support\Collection предоставляет гибкую и удобную обёртку для работы с массивами данных. Например, посмотрите на следующий код. Мы будем использовать хелпер collect, чтобы создать новый экземпляр коллекции из массива, выполним функцию strtoupper для каждого элемента, а затем удалим все пустые элементы:

$collection = collect(['taylor', 'abigail', null])->map(function ($name) {
    return strtoupper($name);
})
->reject(function ($name) {
    return empty($name);
});

Как видите, класс Collection позволяет использовать методы для совершения операций типа map (обработка каждого элемента) и reduce (получение новых структур данных исходя из элементов массива) исходного массива. Коллекции иммутабельны, неизменны, то есть каждый метод класса Collection возвращает совершенно новый экземпляр Collection.

Создание коллекций

Как упоминалось выше, хелпер collect возвращает новый экземпляр класса Illuminate\Support\Collection для заданного массива. Поэтому создать коллекцию очень просто:

$collection = collect([1, 2, 3]);
Результаты запросов Eloquent всегда возвращаются в виде экземпляров класса Collection.

Расширение коллекций

Коллекции могут содержать макросы, что позволяет во время выполнения добавлять дополнительные методы для класса Collection. Например, следующий код добавляет метод 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']

Как правило, вы должны объявлять макросы коллекции в сервис-провайдере.

Доступные методы

В остальной части данной документации, мы будем обсуждать каждый метод, доступный в классе Collection. Помните, все эти методы могут использоваться один за другим для гибкого управления заданным массивом. Кроме того, почти каждый метод возвращает новый экземпляр класса Collection, позволяя вам при необходимости сохранить оригинал коллекции:

all average avg chunk collapse collect combine contains containsStrict count countBy diff diffAssoc diffKeys dump duplicates duplicatesStrict each every except filter first flatMap flatten flip forget forPage get groupBy has implode intersect intersectKey isEmpty isNotEmpty join keyBy keys last map mapWithKeys max median merge mergeRecursive min mode nth only partition pipe pluck pop prepend pull push put random reduce reject replace replaceRecursive reverse search shift shuffle skip slice some sort sortBy sortByDesc sortKeys sortKeysDesc splice split sum take 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 zip

Список методов

all() {#collection-method .first-collection-method}

Метод all возвращает заданный массив, представленный коллекцией:

collect([1, 2, 3])->all();

// [1, 2, 3]

average() {#collection-method}

Псевдоним метода avg.

avg() {#collection-method}

Метод avg возвращает среднее значение переданного ключа:

$average = collect([['foo' => 10], ['foo' => 10], ['foo' => 20], ['foo' => 40]])->avg('foo');

// 20

$average = collect([1, 1, 2, 4])->avg();

// 2

chunk() {#collection-method}

Метод chunk разбивает коллекцию на множество мелких коллекций заданного размера:

$collection = collect([1, 2, 3, 4, 5, 6, 7]);

$chunks = $collection->chunk(4);

$chunks->toArray();

// [[1, 2, 3, 4], [5, 6, 7]]

Этот метод особенно полезен в шаблонах при работе с системой сеток, такой как Bootstrap. Представьте, что у вас есть коллекция моделей Eloquent, которую вы хотите отобразить в сетке:

@foreach ($products->chunk(3) as $chunk)
    

all average avg chunk 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

Обратите внимание, что методы, изменяющие, мутирующие коллекцию (shift, pop, prepend и т.п.) отсуствуют в LazyCollection.

Свои методы ленивых коллекций

В дополнение к методам интерфейса Enumerable, у LazyCollection есть свои уникальные методы:

tapEach() {#collection-method}

В то время как метод each сразу вызывает заданную в аргументах функцию для каждого элемента в коллекции, метод tapEach вызывает её, только когда элементы вытягиваются из списка один за другим:

$lazyCollection = LazyCollection::times(INF)->tapEach(function ($value) {
    dump($value);
});

// Nothing has been dumped so far...

$array = $lazyCollection->take(3)->all();

// 1
// 2
// 3

remember() {#collection-method}

Метод remember возвращает новую ленивую коллекцию, которая запомнит все значения, которые уже были перечислены, и не получит их снова при повторном перечислении коллекции:

$users = User::cursor()->remember();

// запросы в БД не делаются

$users->take(5)->all();

// Выполнится запрос и 5 первых пользователей будут взяты из БД

$users->take(20)->all();

// Первые 5 пользователей будут взяты из кэша, остальные - из БД