Коллекции

Содержание:

Введение

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

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

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

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

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

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

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

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

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

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

// [1, 2, 3]

average()

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

avg()

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

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

// 20

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

// 2

chunk()

Метод chunk разбивает коллекцию на несколько коллекций меньшего объёма данного размера:

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

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

$chunks->toArray();

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

Этот метод особенно полезен в представлениях при работе с модульной сеткой. Представяьте, что у вас есть коллекция модели 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

collapse()

Метод 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]

combine()

Метод combine значение коллекции в качестве ключей со значениями другого массива или коллекции:

$collection = collect(['name', 'age']);

$combined = $collection->combine(['George', 29]);

$combined->all();

// ['name' => 'George', 'age' => 29]

collect()

Метод 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]
Метод collect особенно полезен когда у вас есть экземпляр Enumerable и необходим экзмепляр обычной коллекции. В силу того, что collect() является частью контракта Enumerable, вы можете безопасно использовать его для получения экземпляра Collection.

concat()

Метод 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(['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 для вашиш условий проверки на истину:

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

$collection->contains(function ($value, $key) {
    return $value > 5;
});

// false

Метод contains использует нестрогое сравнение (==) при проверке значений элемента. Это значит, что строка с числовым значением будет равна числу того же значения. Для строго сравнения используется метод containsStrict.

containsStrict()

Метод containsStrict(), в отличие от метода contains, использует строгое сравнение.

count()

Метод count вовращает общее число элементов в коллекции:

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

$collection->count();

// 4

countBy()

Метод countBy считает вхождение значений в коллекцию. По умолчанию, метод считает вхождение каждого элемента:

$collection = collect([1, 2, 2, 2, 3]);

$counted = $collection->countBy();

$counted->all();

// [1 => 1, 2 => 3, 3 => 1]

Однако, вы может передать обартную связь в метод countBy, чтобы сосчитать все элементы пользовательского значения:

$collection = collect(['alice@gmail.com', 'bob@yahoo.com', 'carlos@gmail.com']);

$counted = $collection->countBy(function ($email) {
    return substr(strrchr($email, "@"), 1);
});

$counted->all();

// ['gmail.com' => 2, 'yahoo.com' => 1]

crossJoin()

Метод 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()

Метод dd показывает все элементы коллекции и завершает выполнение скрипта:

$collection = collect(['John Doe', 'Jane Doe']);

$collection->dd();

/*
    Collection {
        #items: array:2 [
            0 => "John Doe"
            1 => "Jane Doe"
        ]
    }
*/

Если вы не хотите останавливать выполенение скрипта, используйте вместо этого метод dump

diff()

Метод diff сравнивает коллекцию с другой коллекцией или массивом PHP. Метод вернёт значения оригинальной коллекции, которые не присутсвуют в другой коллекции или массиве:

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

$diff = $collection->diff([2, 4, 6, 8]);

$diff->all();

// [1, 3, 5]

diffAssoc()

Метод diffAssoc сравнивает коллекцию с другуй коллекцией или массивом. Сравнение основывается на паре ключи и значения. Этот метод вернёт пары ключ / значение в оригинальной коллекции, которые не присутсвуют в представленной:

$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()

Метод diffKeys сравнивает коллекцию с другой коллекцией или массивом, основываясь на их ключах, вне зависимости от их значений. Метод вернёт пары ключ / значение в оригинальной коллекции, которые не присутствуют в выбраной коллекции:

$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()

Метод dump выводит все элементы коллекции:

$collection = collect(['John Doe', 'Jane Doe']);

$collection->dump();

/*
    Collection {
        #items: array:2 [
            0 => "John Doe"
            1 => "Jane Doe"
        ]
    }
*/

Если вы хотите остановить выполнение скрипта после вывода коллекции, используйте метод dd вместо.

duplicates()

Метод duplicates получает и возвращает дубликаты значенией из коллекции:

$collection = collect(['a', 'b', 'a', 'c', 'b']);

$collection->duplicates();

// [2 => 'a', 4 => 'b']

Если коллекция содержит массивы или объекты, вы можете передать ключ атрибута, который вы хотите проверить на дубликаты значений:

$employees = collect([
    ['email' => 'abigail@example.com', 'position' => 'Developer'],
    ['email' => 'james@example.com', 'position' => 'Designer'],
    ['email' => 'victoria@example.com', 'position' => 'Developer'],
])

$employees->duplicates('position');

// [2 => 'Developer']

duplicatesStrict()

Этот метод делает то же, что и метод duplicates, но при этом использует строгое сравнение.

each()

Метод each проводит итерации над элементами коллекции и передает каждый элемент в обратную связь:

$collection->each(function ($item, $key) {
    //
});

Если вы хотите остановить итерацию для элемента, вы можете вернуть false из вашей обратной связи:

$collection->each(function ($item, $key) {
    if (/* some condition */) {
        return false;
    }
});

eachSpread()

Метод eachSpread проводит итерацию над элементами коллекции, передавая каждое вложенное значение элемента в обратную связь:

$collection = collect([['John Doe', 35], ['Jane Doe', 33]]);

$collection->eachSpread(function ($name, $age) {
    //
});

Вы можете остановить перебор элементов путём возврата false из обратной связи:

$collection->eachSpread(function ($name, $age) {
    return false;
});

every()

Метод 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()

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

$collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);

$filtered = $collection->except(['price', 'discount']);

$filtered->all();

// ['product_id' => 1]

Метод only является обратным методом For the inverse of except, see the only method.

filter()

Метод 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]

Метод reject является противоположным методом filter.

first()

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

collect([1, 2, 3, 4])->first(function ($value, $key) {
    return $value > 2;
});

// 3

Вы также может вызвать метод first без аргументов для того, чтобы получить первый элемент коллекции. Если коллекция пуста, вернётся null:

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

// 1

firstWhere()

Метод 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 method, вы можете передавать один аргумент в метод firstWhere. В этом случае, метод firstWhere вернёт первый элемент, в котором данное значение ключа "истина":

$collection->firstWhere('age');

// ['name' => 'Linda', 'age' => 14]

flatMap()

Метод 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()

Метод flatten превращает многомерную коллекцию в одномурную:

$collection = collect(['name' => 'taylor', 'languages' => ['php', 'javascript']]);

$flattened = $collection->flatten();

$flattened->all();

// ['taylor', 'php', 'javascript'];

Также можно передавать в функцию аргумент "глубины":

$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()

Метод flip меняет местами ключи коллекции с их соотвествующими значениями:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$flipped = $collection->flip();

$flipped->all();

// ['taylor' => 'name', 'laravel' => 'framework']

forget()

Метод forget убирает элемент из коллекции по ключу:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$collection->forget('name');

$collection->all();

// ['framework' => 'laravel']
В отличие от других методов, forget не возварщает новую модифицированную коллекцию, а модифицирует текущую.

forPage()

Метод forPage возвращает новую коллекцию содержащую элементы, которые должны присутствовать на данном номере страницы. Метод принимает номер страницы в качестве первого аргумента и количество элементов на странице в качестве второго аргумента:

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

$chunk = $collection->forPage(2, 3);

$chunk->all();

// [4, 5, 6]

get()

Метод get возвращает элемент для данного ключа. Если такого ключа нет, то вернётся null:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$value = $collection->get('name');

// taylor

Вы можете также передать значение по умолчанию в качестве второго аргумента:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$value = $collection->get('foo', 'default-value');

// default-value

Вы можете даже передать функцию в качестве базового значения. Вернётся результат выполнения, если указанный ключе не существует:

$collection->get('email', function () {
    return 'default-value';
});

// default-value

groupBy()

Метод 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->toArray();

/*
    [
        'account-x10' => [
            ['account_id' => 'account-x10', 'product' => 'Chair'],
            ['account_id' => 'account-x10', 'product' => 'Bookcase'],
        ],
        'account-x11' => [
            ['account_id' => 'account-x11', 'product' => 'Desk'],
        ],
    ]
*/

Вместо того, чтобы передавать строку key, вы можете передать функцию, которая и должна вернуть значение ключа для группировки:

$grouped = $collection->groupBy(function ($item, $key) {
    return substr($item['account_id'], -3);
});

$grouped->toArray();

/*
    [
        '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()

Метод 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()

Метод 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()

Метод intersect убирает любые значения из оригинальной коллекции, которая не присутствует в данном массиве или коллекции. Результирующая коллекция сохранит оригинальные ключи коллекции:

$collection = collect(['Desk', 'Sofa', 'Chair']);

$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);

$intersect->all();

// [0 => 'Desk', 2 => 'Chair']

intersectByKeys()

Метод 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()

Метод isEmpty возвращает true, если коллекция пуста, в противном случае, вернётся false:

collect([])->isEmpty();

// true

isNotEmpty()

Метод isNotEmpty возвращает true, когда коллекция не пуста, иначе вернётся false:

collect([])->isNotEmpty();

// false

join()

The join method joins the collection's values with a string:

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()

Метод 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()

Метод 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()

Метод last возвращает последний элемент в коллекции, который удовлетворяет требованию:

collect([1, 2, 3, 4])->last(function ($value, $key) {
    return $value < 3;
});

// 2

Вы также можете вызвать метод last без аргументов для получения последнего элемента в коллекции. Если коллекция пустая, вернётся null:

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

// 4

macro()

Статичный метод macro позволяет вам добавлять методы в класс Collection на ходу. Для большей информации, обратитесь в документацию расширение коллекций.

make()

Статичный метод make создаёт новую коллекцию. Можно обратиться к секции создание коллекций.

map()

Метод map проводит операции на каждый элементом коллекции. После чего, возвращается новая коллекция, которая уже содержит модифицированные элементы и её можно легко модифицировать снова:

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

$multiplied = $collection->map(function ($item, $key) {
    return $item * 2;
});

$multiplied->all();

// [2, 4, 6, 8, 10]
Как и в случае с большинством других методов, map возвращает новые экземпляры коллекции, а не модифицирует элементы вызываемой коллекции. Для того, чтобы трансформировать оригинальную коллекцию, используйте метод transform.

mapInto()

Метод mapInto() перебирает коллекцию, создаёт новый объект класса путём передачи значения в конструктор:

class Currency
{
    /**
     * Create a new currency instance.
     *
     * @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()

Метод 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()

Метод 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->toArray();

/*
    [
        'Sales' => ['John Doe', 'Jane Doe'],
        'Marketing' => ['Johnny Doe'],
    ]
*/

$grouped->get('Sales')->all();

// ['John Doe', 'Jane Doe']

mapWithKeys()

Метод mapWithKeys проводит итерации над коллекцией и передаёт каждое значение в данную функцию, которая должна вернёть ассоциативный массив содержащий пары ключ / значение:

$collection = collect([
    [
        'name' => 'John',
        'department' => 'Sales',
        'email' => 'john@example.com'
    ],
    [
        'name' => 'Jane',
        'department' => 'Marketing',
        'email' => 'jane@example.com'
    ]
]);

$keyed = $collection->mapWithKeys(function ($item) {
    return [$item['email'] => $item['name']];
});

$keyed->all();

/*
    [
        'john@example.com' => 'John',
        'jane@example.com' => 'Jane',
    ]
*/

max()

Метод max возвращает максимальное значение для данного ключа:

$max = collect([['foo' => 10], ['foo' => 20]])->max('foo');

// 20

$max = collect([1, 2, 3, 4, 5])->max();

// 5

median()

Метод median возвращает медианное значение для данного ключа:

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

// 15

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

// 1.5

merge()

Метод 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()

Метод 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 возвращает минимальное значение для данного ключа:

$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');

// 10

$min = collect([1, 2, 3, 4, 5])->min();

// 1

mode()

Метод mode возвращает mode value для данного ключа:

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

// [10]

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

// [1]

nth()

Метод nth создаёт коллекцию, которая содержит каждый n-ый элемент:

$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);

$collection->nth(4);

// ['a', 'e']

Вы можете также передать отступ в качестве второго аргумента:

$collection->nth(4, 1);

// ['b', 'f']

only()

Метод 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.

pad()

Метод pad будет наполнять массив до тех пор, пока не достигнет указанного размера. Поведение метода сходно с функцией PHP array_pad.

Можно указывать отрицательные значения размера для того, чтобы дополянть массив слева. Дополнение не будет проводиться, если длина массива больше или равна указанной длины:

$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()

Метод partition можно использовать вместе с функцией PHP list, чтобы отделить элементы, которые прошли тест от тех, которые не прошли:

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

list($underThree, $equalOrAboveThree) = $collection->partition(function ($i) {
    return $i < 3;
});

$underThree->all();

// [1, 2]

$equalOrAboveThree->all();

// [3, 4, 5, 6]

pipe()

Метод pipe передаёт коллекцию в функцию и возвращает рузультат:

$collection = collect([1, 2, 3]);

$piped = $collection->pipe(function ($collection) {
    return $collection->sum();
});

// 6

pluck()

Метод 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']

Если есть копии ключей, последний походящий элемент будет добавлен в коллекцию:

$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()

Метод pop убирает и возвращает последний элемент коллекции:

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

$collection->pop();

// 5

$collection->all();

// [1, 2, 3, 4]

prepend()

Метод 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()

Метод pull убирает и возвращает элемент из коллекции по ключу:

$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);

$collection->pull('name');

// 'Desk'

$collection->all();

// ['product_id' => 'prod-100']

push()

Метод push добавляет элемент в конец коллекции:

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

$collection->push(5);

$collection->all();

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

put()

Метод put устанавливает данный ключ и значение в коллекции:

$collection = collect(['product_id' => 1, 'name' => 'Desk']);

$collection->put('price', 100);

$collection->all();

// ['product_id' => 1, 'name' => 'Desk', 'price' => 100]

random()

Метод 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)

Если в коллекции меньше элементов, чем запрашивается, тогда метод выкинет ошибку InvalidArgumentException.

reduce()

Метод 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

reject()

Метод reject использует функцию для фильтрации коллекции, которая должна вернуть true, если элемент необходимо удалить из финальной коллекции:

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

$filtered = $collection->reject(function ($value, $key) {
    return $value > 2;
});

$filtered->all();

// [1, 2]

Можно использовать метод filter, для фукнционала противоположного методу reject.

replace()

Метод replace похож на merge; Однако, в дополнение к переписи соединяющихся элементов с ключами, метод replace также перезапишет элементы в коллекции, у которых совпадаются числовые ключи:

$collection = collect(['Taylor', 'Abigail', 'James']);

$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);

$replaced->all();

// ['Taylor', 'Victoria', 'James', 'Finn']

replaceRecursive()

Этот метод поход на метод replace, но он будет проходить массивы рекурсивно и проводить аналогичный процесс замены во внутренних значениях:

$collection = collect(['Taylor', 'Abigail', ['James', 'Victoria', 'Finn']]);

$replaced = $collection->replaceRecursive(['Charlie', 2 => [1 => 'King']]);

$replaced->all();

// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]

reverse()

Метод reverse оборачивает в обратную сторону порядок элементов коллекций, сохраняя оригинальные значения:

$collection = collect(['a', 'b', 'c', 'd', 'e']);

$reversed = $collection->reverse();

$reversed->all();

/*
    [
        4 => 'e',
        3 => 'd',
        2 => 'c',
        1 => 'b',
        0 => 'a',
    ]
*/

search()

Метод search проводит поиск в коллекции по заданному значению и возвращает его ключ если найдёт. Если элемент не найден, вернётся false.

$collection = collect([2, 4, 6, 8]);

$collection->search(4);

// 1

Чтобы использовать "строгое" сравнение, передайте true в качестве второго аргумента в метод:

$collection->search('4', true);

// false

Альтернативно, вы можете передавать вашу функцию, чтобы задать правила поиска:

$collection->search(function ($item, $key) {
    return $item > 5;
});

// 2

shift()

Метод shift убирает и возвращает первый элемент из коллекции:

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

$collection->shift();

// 1

$collection->all();

// [2, 3, 4, 5]

shuffle()

Метод shuffle случайным образом перемешивает элементы в коллекции:

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

$shuffled = $collection->shuffle();

$shuffled->all();

// [3, 2, 5, 1, 4] - (generated randomly)

skip()

Метод 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]

slice()

Метод 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 для переиндексации.

some()

Псевдоним для метода contains.

sort()

Метод sort сортирует коллекцию. Отсортированная коллекция сохраняет оригинальные ключи, поэтому в примере ниже будет использоват метод values для переопределения ключей в соответсвии с числовыми индексами:

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

$sorted = $collection->sort();

$sorted->values()->all();

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

Если вам нужна более сложная сортировка, вы можете написать функцию с вашими алгоритмами. Обратитесь к документации по функции PHP uasort, фактически там рассказывается о механизмах работы метода sort.

Можно использовать методы sortBy и sortByDesc для сортировки сгруппированных массивов или объектов.

sortBy()

Метод 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],
    ]
*/

Вы также можете передать вашу собственную функция для определения того, как сортировать значения коллекции:

$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']],
    ]
*/

sortByDesc()

Этот метод похож на метод sortBy, но проводит сортировку в обратном порядке.

sortKeys()

Метод sortKeys сортирует коллекцию по ключам ассоциативного массива:

$collection = collect([
    'id' => 22345,
    'first' => 'John',
    'last' => 'Doe',
]);

$sorted = $collection->sortKeys();

$sorted->all();

/*
    [
        'first' => 'John',
        'id' => 22345,
        'last' => 'Doe',
    ]
*/

sortKeysDesc()

Этот метод похож на sortKeys, но отлдичие заключается в том, что проводится сортировка в обратном порядке.

splice()

Метод 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()

Метод split разбивает коллекцию на указанное число групп:

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

$groups = $collection->split(3);

$groups->toArray();

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

sum()

Метод 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()

Метод 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]

tap()

Метод tap передаёт коллекцию функцию, которая посзволяет вам, вклиниваться в коллекцию на определённом месте, проводить некоторые действия на элементами, при этом не затрагивая коллекцию:

collect([2, 4, 3, 1, 5])
    ->sort()
    ->tap(function ($collection) {
        Log::debug('Values after sorting', $collection->values()->toArray());
    })
    ->shift();

// 1

times()

Статичный метод times создаёт новую коллекцию используя функцию определённое количество раз:

$collection = Collection::times(10, function ($number) {
    return $number * 9;
});

$collection->all();

// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]

Этот метод может быть полезен при комбинировании с фабриками для создания моделей Eloquent:

$categories = Collection::times(3, function ($number) {
    return factory(Category::class)->create(['name' => "Category No. $number"]);
});

$categories->all();

/*
    [
        ['id' => 1, 'name' => 'Category #1'],
        ['id' => 2, 'name' => 'Category #2'],
        ['id' => 3, 'name' => 'Category #3'],
    ]
*/

toArray()

Метод toArray преобразовывает коллекцию в обычный PHP массив. Если значеиня коллекции являются также моделями Eloquent, то и они тоже будет преобразованы в массивы:

$collection = collect(['name' => 'Desk', 'price' => 200]);

$collection->toArray();

/*
    [
        ['name' => 'Desk', 'price' => 200],
    ]
*/
toArray преобразовывает все объекты коллекции, которые возможно, в массивы. Чтобы получить строку, используйте метод all.

toJson()

Метод toJson преобразовывает коллекцию в строку JSON:

$collection = collect(['name' => 'Desk', 'price' => 200]);

$collection->toJson();

// '{"name":"Desk", "price":200}'

transform()

Метод transform проходит по каждому элементу коллекции и проводит действия, указанные в функции, результат возвращается и проводится замена исходного значения конечным:

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

$collection->transform(function ($item, $key) {
    return $item * 2;
});

$collection->all();

// [2, 4, 6, 8, 10]
В отличие от других методов коллекции, метод transform изменяет исходную коллекцию. Чтобы вместо этого создавать новую, используйте метод map.

union()

Метод union добавляет предоставленный массив в коллекцию. Если массив содержит ключи, которые уже содержатся в оригинальной коллекции, приоритет отдаётся оригинальным ключам:

$collection = collect([1 => ['a'], 2 => ['b']]);

$union = $collection->union([3 => ['c'], 1 => ['b']]);

$union->all();

// [1 => ['a'], 2 => ['b'], 3 => ['c']]

unique()

Метод 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 = $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()

Этот метод похож на метод unique, но использует строгое сравнение.

unless()

Метод 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.

unlessEmpty()

Метод является псевдонимом для метода whenNotEmpty.

unlessNotEmpty()

Псевдоним для метода whenEmpty.

unwrap()

Статичный метод unwrap возвращает элементы базовой коллекции из данного значения при необходимости:

Collection::unwrap(collect('John Doe'));

// ['John Doe']

Collection::unwrap(['John Doe']);

// ['John Doe']

Collection::unwrap('John Doe');

// 'John Doe'

values()

Метод 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()

Метод 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]

Для противоположного эффекта, обратитесь к методу unless.

whenEmpty()

Метод 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']

$collection = collect(['michael', 'tom']);

$collection->whenEmpty(function($collection) {
    return $collection->push('adam');
}, function($collection) {
    return $collection->push('taylor');
});

$collection->all();

// ['michael', 'tom', 'taylor']

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();

// []

$collection = collect();

$collection->whenNotEmpty(function($collection) {
    return $collection->push('adam');
}, function($collection) {
    return $collection->push('taylor');
});

$collection->all();

// ['taylor']

where()

Метод 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 использует нестрогие сравнения для проверки значений. На рпактике эта означает, что строка с числовым значением будет приравнена числу такой же величины.

Дополнитлеьно, можно передавать оператор сравнения в качестве второго параметра.

$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'],
    ]
*/

whereStrict()

Этот метод имеет такую же функцианальность, как и метод where; Однако, используется строгое сравнение.

whereBetween()

Метод 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()

Метод 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' => 'Bookcase', 'price' => 150],
        ['product' => 'Desk', 'price' => 200],
    ]
*/

Метод whereIn использует нестрогое сравнение.

whereInStrict()

Метод whereInStrict() схож с методом whereIn, но использует строгое сравнение.

whereInstanceOf()

Метод whereInstanceOf фильтрует коллекцию по данному типу класса:

$collection = collect([
    new User,
    new User,
    new Post,
]);

return $collection->whereInstanceOf(User::class);

whereNotBetween()

Метод 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()

Метод 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, однако использует строгое сравнение.

wrap()

Статичный метод wrap обёртывает значение в коллекцию:

$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()

Метод 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, some, sortBy, sortByDesc, sum, и unique.

Каждое сообщение высшего порядка можно использовать как динамическое свойство коллекции. Например, давайте используем сообщение each для применения метода к каждому объекту внутри коллекции:

$users = User::where('votes', '>', 500)->get();

$users->each->markAsVip();

Мы можем использовать сообщение высшего порядка sum для определения общего числа голосов для коллекции пользователей:

$users = User::where('group', 'Development')->get();

return $users->sum->votes;

Ленивые коллекции

Введение

Перед тем как приступить к изучению "ленивых" коллекций Ларавел, обратитесь к документации PHP генараторы.

Для поддержки уже мощного класса Collection, класс LazyCollection использует PHP генараторы, чтобы позволить работать с очень большими базами данных, в то же время, не задействуя использование памяти.

Например, представьте что вашему приложению необходимо взаимодействовать с лог-файлом размером сотни гигабайт. Вместо того, чтобы пытаться загрузить файл полностью одномоментно, "ленивые" коллекции могут быть испоьзованы, чтобы сохранить только малую часть файла в памяти за данное время:

use App\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 будет загружаться в память:

$users = App\User::all()->filter(function ($user) {
    return $user->id > 500;
});

Однако, метод построителя запросов cursor возвращает экземпляр LazyCollection. Это позволяет вам и выполнить только один запрос к базе данных и также держать в памяти только одну модель Eloquent. В этом примере, функция filter не выполняется до тех пор, пока мы не прошли по каждому пользователю индивидуально. Этот позволяет просто невероятным темпами снизить потребление памяти:

$users = App\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, который определяет следующие методы:

Методы, которые проводит измения на коллекцией *(такиек как shift, pop, prepend) не доступны для класса LazyCollection.

Методы ленивый коллекций

Дополнительно, к методам определённым в контракте Enumerable, класс LazyCollection содержит следующие методы:

tapEach()

В то время как метод 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