Колекції · Laravel
Вступ
Клас Illuminate\Support\Collection дає зручну плавну обгортку для роботи з масивами даних. Наприклад, погляньте на такий код. Скористаємося хелпером collect, щоб створити новий екземпляр колекції з масиву, застосуємо до кожного елемента функцію strtoupper, а потім приберемо всі порожні елементи:
$collection = collect(['Taylor', 'Abigail', null])->map(function (?string $name) {
return strtoupper($name);
})->reject(function (string $name) {
return empty($name);
});
Як бачите, клас Collection дозволяє ланцюжком викликати методи, плавно виконуючи перетворення й згортання базового масиву. Загалом колекції незмінні: кожен метод Collection повертає цілком новий екземпляр Collection.
Створення колекцій
Як згадано вище, хелпер collect повертає новий екземпляр Illuminate\Support\Collection для переданого масиву. Тож створити колекцію просто:
$collection = collect([1, 2, 3]);
Колекцію також можна створити методами make і fromJson.
Примітка Результати запитів Eloquent завжди повертаються як екземпляри
Collection.
Розширення колекцій
Колекції підтримують макроси ("macroable"), тому до класу Collection можна додавати додаткові методи під час виконання. Метод macro класу Illuminate\Support\Collection приймає замикання, яке виконається під час виклику вашого макроса. Усередині цього замикання доступні інші методи колекції через $this, так само як у справжньому методі класу колекції. Наприклад, наступний код додає до класу Collection метод toUpper:
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
Collection::macro('toUpper', function () {
return $this->map(function (string $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 (string $locale) {
return $this->map(function (string $value) use ($locale) {
return Lang::get($value, [], $locale);
});
});
$collection = collect(['first', 'second']);
$translated = $collection->toLocale('es');
// ['primero', 'segundo'];
Доступні методи
Більша частина решти документації про колекції присвячена окремим методам класу Collection. Памʼятайте: усі ці методи можна поєднувати в ланцюжок, плавно змінюючи базовий масив. До того ж майже кожен метод повертає новий екземпляр Collection, тож за потреби ви зберігаєте початкову копію колекції:
after all average avg before chunk chunkBy chunkWhile collapse collapseWithKeys collect combine concat contains containsStrict count countBy crossJoin dd diff diffAssoc diffAssocUsing diffKeys doesntContain doesntContainStrict dot dump duplicates duplicatesStrict each eachSpread ensure every except filter first firstOrFail firstWhere flatMap flatten flip forget forPage fromJson get groupBy has hasAny hasMany hasSole implode intersect intersectUsing intersectAssoc intersectAssocUsing intersectByKeys isEmpty isNotEmpty join keyBy keys last lazy macro make map mapInto mapSpread mapToGroups mapWithKeys max median merge mergeRecursive min mode multiply nth only pad partition percentage pipe pipeInto pipeThrough pluck pop prepend pull push put random range reduce reduceInto reduceSpread reject replace replaceRecursive reverse search select shift shuffle skip skipUntil skipWhile slice sliding sole some sort sortBy sortByDesc sortDesc sortKeys sortKeysDesc sortKeysUsing splice split splitIn sum take takeUntil takeWhile tap times toArray toJson toPrettyJson transform undot union unique uniqueStrict unless unlessEmpty unlessNotEmpty unwrap value values when whenEmpty whenNotEmpty where whereStrict whereBetween whereIn whereInStrict whereInstanceOf whereNotBetween whereNotIn whereNotInStrict whereNotNull whereNull wrap zip
Перелік методів
after()
Метод after повертає елемент, що йде після заданого. Якщо заданий елемент не знайдено або він останній, повертається null:
$collection = collect([1, 2, 3, 4, 5]);
$collection->after(3);
// 4
$collection->after(5);
// null
Цей метод шукає заданий елемент через "нестроге" порівняння: рядок із цілим числом вважається рівним цілому числу того самого значення. Щоб застосувати "строге" порівняння, передайте методу аргумент strict:
collect([2, 4, 6, 8])->after('4', strict: true);
// null
Також можна передати власне замикання, щоб знайти перший елемент, який проходить задану перевірку:
collect([2, 4, 6, 8])->after(function (int $item, int $key) {
return $item > 5;
});
// 8
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
before()
Метод before протилежний до методу after. Він повертає елемент, що стоїть перед заданим. Якщо заданий елемент не знайдено або він перший, повертається null:
$collection = collect([1, 2, 3, 4, 5]);
$collection->before(3);
// 2
$collection->before(1);
// null
collect([2, 4, 6, 8])->before('4', strict: true);
// null
collect([2, 4, 6, 8])->before(function (int $item, int $key) {
return $item > 5;
});
// 4
chunk()
Метод chunk розбиває колекцію на кілька менших колекцій заданого розміру:
$collection = collect([1, 2, 3, 4, 5, 6, 7]);
$chunks = $collection->chunk(4);
$chunks->all();
// [[1, 2, 3, 4], [5, 6, 7]]
Метод особливо корисний у представленнях (view) під час роботи з сітковою системою на кшталт 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
chunkBy()
Метод chunkBy розбиває колекцію на кілька менших колекцій, групуючи сусідні елементи з однаковим значенням за заданим ключем або колбеком. Наприклад, можна згрупувати сусідні товари зі спільним батьківським елементом:
$chunks = $products->chunkBy('parent');
На відміну від методу groupBy, елементи з однаковим значенням, які не є сусідніми, потрапляють у різні частини:
$collection = collect([1, 1, 2, 2, 1]);
$chunks = $collection->chunkBy(fn (int $value) => $value);
$chunks->all();
// [[1, 1], [2, 2], [1]]
chunkWhile()
Метод chunkWhile розбиває колекцію на кілька менших колекцій на основі результату заданого колбека. Змінна $chunk, передана в замикання, дозволяє звернутися до попереднього елемента:
$collection = collect(str_split('AABBCCCD'));
$chunks = $collection->chunkWhile(function (string $value, int $key, Collection $chunk) {
return $value === $chunk->last();
});
$chunks->all();
// [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]
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]
collapseWithKeys()
Метод collapseWithKeys зводить колекцію масивів або колекцій в одну колекцію, зберігаючи початкові ключі. Якщо колекція вже пласка, повернеться порожня колекція:
$collection = collect([
['first' => collect([1, 2, 3])],
['second' => [4, 5, 6]],
['third' => collect([7, 8, 9])]
]);
$collapsed = $collection->collapseWithKeys();
$collapsed->all();
// [
// 'first' => [1, 2, 3],
// 'second' => [4, 5, 6],
// 'third' => [7, 8, 9],
// ]
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();
$collection::class;
// 'Illuminate\Support\Collection'
$collection->all();
// [1, 2, 3]
Примітка Метод
collectособливо стане в пригоді, коли у вас є екземплярEnumerable, а потрібен нелінивий екземпляр колекції. Оскількиcollect()входить до контрактуEnumerable, ним можна безпечно отримати екземплярCollection.
combine()
Метод combine поєднує значення колекції як ключі зі значеннями іншого масиву чи колекції:
$collection = collect(['name', 'age']);
$combined = $collection->combine(['George', 29]);
$combined->all();
// ['name' => 'George', 'age' => 29]
concat()
Метод concat додає значення заданого масиву або колекції в кінець іншої колекції:
$collection = collect(['John Doe']);
$concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']);
$concatenated->all();
// ['John Doe', 'Jane Doe', 'Johnny Doe']
Метод concat числово переіндексовує ключі для елементів, доданих до початкової колекції. Щоб зберегти ключі в асоціативних колекціях, дивіться метод merge.
contains()
Метод contains визначає, чи містить колекція заданий елемент. Йому можна передати замикання, щоб перевірити, чи існує в колекції елемент, який проходить задану перевірку:
$collection = collect([1, 2, 3, 4, 5]);
$collection->contains(function (int $value, int $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 - метод doesntContain.
containsStrict()
Цей метод має ту саму сигнатуру, що й contains, проте всі значення порівнюються "строго".
Примітка Поведінка цього методу змінюється під час роботи з колекціями Eloquent.
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 (string $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();
/*
array:2 [
0 => "John Doe"
1 => "Jane Doe"
]
*/
Якщо зупиняти виконання скрипта не потрібно, скористайтеся методом dump.
diff()
Метод diff порівнює колекцію з іншою колекцією або звичайним PHP-масивом array за значеннями. Метод поверне ті значення початкової колекції, яких немає в заданій:
$collection = collect([1, 2, 3, 4, 5]);
$diff = $collection->diff([2, 4, 6, 8]);
$diff->all();
// [1, 3, 5]
Примітка Поведінка цього методу змінюється під час роботи з колекціями Eloquent.
diffAssoc()
Метод diffAssoc порівнює колекцію з іншою колекцією або звичайним PHP-масивом array за ключами і значеннями. Метод поверне ті пари ключ / значення початкової колекції, яких немає в заданій:
$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]
diffAssocUsing()
На відміну від diffAssoc, метод diffAssocUsing приймає задану користувачем функцію-колбек для порівняння індексів:
$collection = collect([
'color' => 'orange',
'type' => 'fruit',
'remain' => 6,
]);
$diff = $collection->diffAssocUsing([
'Color' => 'yellow',
'Type' => 'fruit',
'Remain' => 3,
], 'strnatcasecmp');
$diff->all();
// ['color' => 'orange', 'remain' => 6]
Колбек має бути функцією порівняння, яка повертає ціле число менше за нуль, рівне нулю або більше за нуль. Докладніше - у документації PHP щодо array_diff_uassoc: саме цю PHP-функцію метод diffAssocUsing використовує всередині.
diffKeys()
Метод diffKeys порівнює колекцію з іншою колекцією або звичайним PHP-масивом array за ключами. Метод поверне ті пари ключ / значення початкової колекції, яких немає в заданій:
$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]
doesntContain()
Метод doesntContain визначає, чи не містить колекція заданий елемент. Йому можна передати замикання, щоб перевірити, чи немає в колекції елемента, який проходить задану перевірку:
$collection = collect([1, 2, 3, 4, 5]);
$collection->doesntContain(function (int $value, int $key) {
return $value < 5;
});
// false
Або ж передайте методу doesntContain рядок, щоб перевірити, чи не містить колекція задане значення:
$collection = collect(['name' => 'Desk', 'price' => 100]);
$collection->doesntContain('Table');
// true
$collection->doesntContain('Desk');
// false
Також методу doesntContain можна передати пару ключ / значення, і він визначить, чи немає такої пари в колекції:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
]);
$collection->doesntContain('product', 'Bookcase');
// true
Перевіряючи значення елементів, метод doesntContain використовує "нестроге" порівняння: рядок із цілим числом вважається рівним цілому числу того самого значення.
doesntContainStrict()
Цей метод має ту саму сигнатуру, що й doesntContain, проте всі значення порівнюються "строго".
dot()
Метод dot зводить багатовимірну колекцію до одного рівня, використовуючи "крапкову" нотацію для позначення глибини:
$collection = collect(['products' => ['desk' => ['price' => 100]]]);
$flattened = $collection->dot();
$flattened->all();
// ['products.desk.price' => 100]
dump()
Метод dump виводить елементи колекції:
$collection = collect(['John Doe', 'Jane Doe']);
$collection->dump();
/*
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 = collect([1, 2, 3, 4]);
$collection->each(function (int $item, int $key) {
// ...
});
Щоб зупинити обхід елементів, поверніть із замикання false:
$collection->each(function (int $item, int $key) {
if (/* умова */) {
return false;
}
});
eachSpread()
Метод eachSpread проходить елементи колекції, передаючи кожне значення вкладеного елемента в заданий колбек:
$collection = collect([['John Doe', 35], ['Jane Doe', 33]]);
$collection->eachSpread(function (string $name, int $age) {
// ...
});
Зупинити обхід елементів можна, повернувши з колбека false:
$collection->eachSpread(function (string $name, int $age) {
return false;
});
ensure()
Метод ensure перевіряє, що всі елементи колекції належать до заданого типу або списку типів. Інакше буде викинуто UnexpectedValueException:
return $collection->ensure(User::class);
return $collection->ensure([User::class, Customer::class]);
Можна вказувати й примітивні типи, як-от string, int, float, bool та array:
return $collection->ensure('int');
Увага Метод
ensureне гарантує, що згодом до колекції не додадуть елементи інших типів.
every()
Метод every перевіряє, що всі елементи колекції проходять задану перевірку:
collect([1, 2, 3, 4])->every(function (int $value, int $key) {
return $value > 2;
});
// false
Якщо колекція порожня, метод every поверне true:
$collection = collect([]);
$collection->every(function (int $value, int $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]
Протилежність except - метод only.
Примітка Поведінка цього методу змінюється під час роботи з колекціями Eloquent.
filter()
Метод filter фільтрує колекцію заданим колбеком, лишаючи тільки ті елементи, які проходять перевірку:
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->filter(function (int $value, int $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()
Метод first повертає перший елемент колекції, який проходить задану перевірку:
collect([1, 2, 3, 4])->first(function (int $value, int $key) {
return $value > 2;
});
// 3
Метод first можна викликати й без аргументів, щоб отримати перший елемент колекції. Якщо колекція порожня, повертається null:
collect([1, 2, 3, 4])->first();
// 1
firstOrFail()
Метод firstOrFail ідентичний методу first, проте якщо результату не знайдено, буде викинуто виняток Illuminate\Support\ItemNotFoundException:
collect([1, 2, 3, 4])->firstOrFail(function (int $value, int $key) {
return $value > 5;
});
// Викидає ItemNotFoundException...
Метод firstOrFail можна викликати й без аргументів, щоб отримати перший елемент колекції. Якщо колекція порожня, буде викинуто виняток Illuminate\Support\ItemNotFoundException:
collect([])->firstOrFail();
// Викидає ItemNotFoundException...
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, методу firstWhere можна передати один аргумент. Тоді firstWhere поверне перший елемент, у якого значення за заданим ключем є "істинним":
$collection->firstWhere('age');
// ['name' => 'Linda', 'age' => 14]
flatMap()
Метод flatMap проходить колекцію і передає кожне значення в задане замикання. Замикання може змінити елемент і повернути його, формуючи нову колекцію змінених елементів. Далі масив зводиться на один рівень:
$collection = collect([
['name' => 'Sally'],
['school' => 'Arkansas'],
['age' => 28]
]);
$flattened = $collection->flatMap(function (array $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'];
За потреби методу 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()
Метод 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');
// ['framework' => 'Laravel']
// Забути кілька ключів...
$collection->forget(['name', 'framework']);
// []
Увага На відміну від більшості інших методів колекцій,
forgetне повертає нову змінену колекцію: він змінює й повертає ту колекцію, на якій його викликано.
forPage()
Метод forPage повертає нову колекцію з елементами, які були б на заданій сторінці. Перший аргумент - номер сторінки, другий - кількість елементів на сторінку:
$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);
$chunk = $collection->forPage(2, 3);
$chunk->all();
// [4, 5, 6]
fromJson()
Статичний метод fromJson створює новий екземпляр колекції, декодуючи заданий JSON-рядок PHP-функцією json_decode:
use Illuminate\Support\Collection;
$json = json_encode([
'name' => 'Taylor Otwell',
'role' => 'Developer',
'status' => 'Active',
]);
$collection = Collection::fromJson($json);
get()
Метод 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 'taylor@example.com';
});
// taylor@example.com
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->all();
/*
[
'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 (array $item, int $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 (array $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
hasAny()
Метод hasAny визначає, чи існує в колекції хоча б один із заданих ключів:
$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);
$collection->hasAny(['product', 'price']);
// true
$collection->hasAny(['name', 'price']);
// false
hasMany()
Метод hasMany визначає, чи містить колекція кілька елементів:
collect([])->hasMany();
// false
collect(['1'])->hasMany();
// false
collect([1, 2, 3])->hasMany();
// true
collect([
['age' => 2],
['age' => 3],
])->hasMany(fn ($item) => $item['age'] === 2)
// false
hasSole()
Метод hasSole визначає, чи містить колекція рівно один елемент, за потреби - такий, що відповідає заданому критерію:
collect([])->hasSole();
// false
collect(['1'])->hasSole();
// true
collect([1, 2, 3])->hasSole(fn (int $item) => $item === 2);
// true
implode()
Метод implode зʼєднує елементи колекції. Його аргументи залежать від типу елементів у колекції. Якщо колекція містить масиви або обʼєкти, передайте ключ атрибутів, які хочете зʼєднати, і рядок-роздільник ("glue"), який має стояти між значеннями:
$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'
Методу implode можна передати замикання, якщо потрібно відформатувати значення, які зʼєднуються:
$collection->implode(function (array $item, int $key) {
return strtoupper($item['product']);
}, ', ');
// 'DESK, CHAIR'
intersect()
Метод intersect прибирає з початкової колекції всі значення, яких немає в заданому масиві чи колекції. Отримана колекція збереже ключі початкової:
$collection = collect(['Desk', 'Sofa', 'Chair']);
$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);
$intersect->all();
// [0 => 'Desk', 2 => 'Chair']
Примітка Поведінка цього методу змінюється під час роботи з колекціями Eloquent.
intersectUsing()
Метод intersectUsing прибирає з початкової колекції всі значення, яких немає в заданому масиві чи колекції, використовуючи для порівняння значень власний колбек. Отримана колекція збереже ключі початкової:
$collection = collect(['Desk', 'Sofa', 'Chair']);
$intersect = $collection->intersectUsing(['desk', 'chair', 'bookcase'], function (string $a, string $b) {
return strcasecmp($a, $b);
});
$intersect->all();
// [0 => 'Desk', 2 => 'Chair']
intersectAssoc()
Метод intersectAssoc порівнює початкову колекцію з іншою колекцією або масивом і повертає пари ключ / значення, наявні в усіх заданих колекціях:
$collection = collect([
'color' => 'red',
'size' => 'M',
'material' => 'cotton'
]);
$intersect = $collection->intersectAssoc([
'color' => 'blue',
'size' => 'M',
'material' => 'polyester'
]);
$intersect->all();
// ['size' => 'M']
intersectAssocUsing()
Метод intersectAssocUsing порівнює початкову колекцію з іншою колекцією або масивом і повертає пари ключ / значення, наявні в обох, використовуючи власний колбек порівняння для визначення рівності і ключів, і значень:
$collection = collect([
'color' => 'red',
'Size' => 'M',
'material' => 'cotton',
]);
$intersect = $collection->intersectAssocUsing([
'color' => 'blue',
'size' => 'M',
'material' => 'polyester',
], function (string $a, string $b) {
return strcasecmp($a, $b);
});
$intersect->all();
// ['Size' => 'M']
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()
Метод 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()
Метод 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 (array $item, int $key) {
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 (int $value, int $key) {
return $value < 3;
});
// 2
Метод last можна викликати й без аргументів, щоб отримати останній елемент колекції. Для порожньої колекції повертається null:
collect([1, 2, 3, 4])->last();
// 4
lazy() {.collection-method}
Метод lazy повертає новий екземпляр LazyCollection із наявного масиву елементів:
$lazyCollection = collect([1, 2, 3, 4])->lazy();
$lazyCollection::class;
// Illuminate\Support\LazyCollection
$lazyCollection->all();
// [1, 2, 3, 4]
Це особливо корисно, коли треба виконати перетворення над величезною Collection із великою кількістю елементів:
$count = $hugeCollection
->lazy()
->where('country', 'FR')
->where('balance', '>', '100')
->count();
Перетворивши колекцію на LazyCollection, ми уникаємо виділення купи додаткової памʼяті. Хоч початкова колекція й далі тримає свої значення в памʼяті, наступні фільтри вже цього не роблять. Тож під час фільтрації результатів колекції додаткова памʼять фактично не виділяється.
macro() {.collection-method}
Статичний метод macro дає змогу додавати методи до класу Collection під час виконання. Докладніше в документації про розширення колекцій.
make() {.collection-method}
Статичний метод make створює новий екземпляр колекції. Див. розділ Створення колекцій.
use Illuminate\Support\Collection;
$collection = Collection::make([1, 2, 3]);
map() {.collection-method}
Метод map проходить колекцію і передає кожне значення в заданий колбек. Колбек може змінити елемент і повернути його, утворюючи таким чином нову колекцію зі зміненими елементами:
$collection = collect([1, 2, 3, 4, 5]);
$multiplied = $collection->map(function (int $item, int $key) {
return $item * 2;
});
$multiplied->all();
// [2, 4, 6, 8, 10]
[!WARNING] Як і більшість інших методів колекції,
mapповертає новий екземпляр колекції; він не змінює колекцію, на якій його викликано. Щоб перетворити початкову колекцію, використовуйте метод transform.
mapInto() {.collection-method}
Метод mapInto() проходить колекцію і створює новий екземпляр заданого класу, передаючи значення в конструктор:
class Currency
{
/**
* Create a new currency instance.
*/
function __construct(
public string $code,
) {}
}
$collection = collect(['USD', 'EUR', 'GBP']);
$currencies = $collection->mapInto(Currency::class);
$currencies->all();
// [Currency('USD'), Currency('EUR'), Currency('GBP')]
mapSpread() {.collection-method}
Метод mapSpread проходить елементи колекції, передаючи кожне значення вкладеного елемента в задане замикання. Замикання може змінити елемент і повернути його, утворюючи нову колекцію зі зміненими елементами:
$collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
$chunks = $collection->chunk(2);
$sequence = $chunks->mapSpread(function (int $even, int $odd) {
return $even + $odd;
});
$sequence->all();
// [1, 5, 9, 13, 17]
mapToGroups() {.collection-method}
Метод mapToGroups групує елементи колекції за заданим замиканням. Замикання має повернути асоціативний масив з однією парою ключ / значення, утворюючи нову колекцію згрупованих значень:
$collection = collect([
[
'name' => 'John Doe',
'department' => 'Sales',
],
[
'name' => 'Jane Doe',
'department' => 'Sales',
],
[
'name' => 'Johnny Doe',
'department' => 'Marketing',
]
]);
$grouped = $collection->mapToGroups(function (array $item, int $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-method}
Метод mapWithKeys проходить колекцію і передає кожне значення в заданий колбек. Колбек має повернути асоціативний масив з однією парою ключ / значення:
$collection = collect([
[
'name' => 'John',
'department' => 'Sales',
'email' => 'john@example.com',
],
[
'name' => 'Jane',
'department' => 'Marketing',
'email' => 'jane@example.com',
]
]);
$keyed = $collection->mapWithKeys(function (array $item, int $key) {
return [$item['email'] => $item['name']];
});
$keyed->all();
/*
[
'john@example.com' => 'John',
'jane@example.com' => 'Jane',
]
*/
max() {.collection-method}
Метод max повертає максимальне значення за заданим ключем:
$max = collect([
['foo' => 10],
['foo' => 20]
])->max('foo');
// 20
$max = collect([1, 2, 3, 4, 5])->max();
// 5
median() {.collection-method}
Метод 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-method}
Метод 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-method}
Метод 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() {.collection-method}
Метод min повертає мінімальне значення за заданим ключем:
$min = collect([
['foo' => 10],
['foo' => 20]
])->min('foo');
// 10
$min = collect([1, 2, 3, 4, 5])->min();
// 1
mode() {.collection-method}
Метод 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]
multiply() {.collection-method}
Метод multiply створює вказану кількість копій усіх елементів колекції:
$users = collect([
['name' => 'User #1', 'email' => 'user1@example.com'],
['name' => 'User #2', 'email' => 'user2@example.com'],
])->multiply(3);
/*
[
['name' => 'User #1', 'email' => 'user1@example.com'],
['name' => 'User #2', 'email' => 'user2@example.com'],
['name' => 'User #1', 'email' => 'user1@example.com'],
['name' => 'User #2', 'email' => 'user2@example.com'],
['name' => 'User #1', 'email' => 'user1@example.com'],
['name' => 'User #2', 'email' => 'user2@example.com'],
]
*/
nth() {.collection-method}
Метод nth створює нову колекцію з кожного n-го елемента:
$collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);
$collection->nth(4);
// ['a', 'e']
Другим аргументом можна за бажанням передати початковий зсув:
$collection->nth(4, 1);
// ['b', 'f']
only() {.collection-method}
Метод 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.
[!NOTE] Поведінка цього методу змінюється при використанні колекцій Eloquent.
pad() {.collection-method}
Метод 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() {.collection-method}
Метод partition можна поєднати з деструктуризацією масивів PHP, щоб відокремити елементи, які проходять задану перевірку, від тих, які її не проходять:
$collection = collect([1, 2, 3, 4, 5, 6]);
[$underThree, $equalOrAboveThree] = $collection->partition(function (int $i) {
return $i < 3;
});
$underThree->all();
// [1, 2]
$equalOrAboveThree->all();
// [3, 4, 5, 6]
[!NOTE] Поведінка цього методу змінюється при роботі з колекціями Eloquent.
percentage() {.collection-method}
Метод percentage дає змогу швидко визначити відсоток елементів колекції, які проходять задану перевірку:
$collection = collect([1, 1, 2, 2, 2, 3]);
$percentage = $collection->percentage(fn (int $value) => $value === 1);
// 33.33
Типово відсоток округлюється до двох знаків після коми. Цю поведінку можна змінити, передавши методу другий аргумент:
$percentage = $collection->percentage(fn (int $value) => $value === 1, precision: 3);
// 33.333
pipe() {.collection-method}
Метод pipe передає колекцію в задане замикання і повертає результат його виконання:
$collection = collect([1, 2, 3]);
$piped = $collection->pipe(function (Collection $collection) {
return $collection->sum();
});
// 6
pipeInto() {.collection-method}
Метод pipeInto створює новий екземпляр заданого класу і передає колекцію в конструктор:
class ResourceCollection
{
/**
* Create a new ResourceCollection instance.
*/
public function __construct(
public Collection $collection,
) {}
}
$collection = collect([1, 2, 3]);
$resource = $collection->pipeInto(ResourceCollection::class);
$resource->collection->all();
// [1, 2, 3]
pipeThrough() {.collection-method}
Метод pipeThrough передає колекцію в заданий масив замикань і повертає результат їх виконання:
use Illuminate\Support\Collection;
$collection = collect([1, 2, 3]);
$result = $collection->pipeThrough([
function (Collection $collection) {
return $collection->merge([4, 5]);
},
function (Collection $collection) {
return $collection->sum();
},
]);
// 15
pluck() {.collection-method}
Метод 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([
[
'name' => 'Laracon',
'speakers' => [
'first_day' => ['Rosa', 'Judith'],
],
],
[
'name' => 'VueConf',
'speakers' => [
'first_day' => ['Abigail', 'Joey'],
],
],
]);
$plucked = $collection->pluck('speakers.first_day');
$plucked->all();
// [['Rosa', 'Judith'], ['Abigail', 'Joey']]
Якщо трапляються дублікати ключів, у результуючу колекцію потрапить останній збіг:
$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-method}
Метод pop видаляє й повертає останній елемент колекції. Якщо колекція порожня, повертається null:
$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-method}
Метод 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-method}
Метод pull видаляє й повертає елемент колекції за його ключем:
$collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);
$collection->pull('name');
// 'Desk'
$collection->all();
// ['product_id' => 'prod-100']
push() {.collection-method}
Метод push додає елемент у кінець колекції:
$collection = collect([1, 2, 3, 4]);
$collection->push(5);
$collection->all();
// [1, 2, 3, 4, 5]
Можна також передати кілька елементів для додавання в кінець колекції:
$collection = collect([1, 2, 3, 4]);
$collection->push(5, 6, 7);
$collection->all();
// [1, 2, 3, 4, 5, 6, 7]
put() {.collection-method}
Метод put встановлює задані ключ і значення в колекції:
$collection = collect(['product_id' => 1, 'name' => 'Desk']);
$collection->put('price', 100);
$collection->all();
// ['product_id' => 1, 'name' => 'Desk', 'price' => 100]
random() {.collection-method}
Метод random повертає випадковий елемент колекції:
$collection = collect([1, 2, 3, 4, 5]);
$collection->random();
// 4 - (отримано випадково)
Методу random можна передати ціле число, щоб указати, скільки елементів отримати випадково. Коли кількість потрібних елементів передано явно, завжди повертається колекція елементів:
$random = $collection->random(3);
$random->all();
// [2, 4, 5] - (отримано випадково)
Якщо в екземплярі колекції менше елементів, ніж запитано, метод random викине InvalidArgumentException.
Метод random також приймає замикання, яке отримає поточний екземпляр колекції:
use Illuminate\Support\Collection;
$random = $collection->random(fn (Collection $items) => min(10, count($items)));
$random->all();
// [1, 2, 3, 4, 5] - (отримано випадково)
range() {.collection-method}
Метод range повертає колекцію з цілими числами у вказаному діапазоні:
$collection = collect()->range(3, 6);
$collection->all();
// [3, 4, 5, 6]
reduce() {.collection-method}
Метод reduce зводить колекцію до одного значення, передаючи результат кожної ітерації в наступну:
$collection = collect([1, 2, 3]);
$total = $collection->reduce(function (?int $carry, int $item) {
return $carry + $item;
});
// 6
На першій ітерації значення $carry дорівнює null; проте початкове значення можна задати, передавши методу reduce другий аргумент:
$collection->reduce(function (int $carry, int $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 (int $carry, int $value, string $key) use ($ratio) {
return $carry + ($value * $ratio[$key]);
}, 0);
// 4264
reduceInto() {.collection-method}
Метод reduceInto зводить колекцію до одного значення, змінюючи задане початкове значення. На відміну від методу reduce, заданий колбек не мусить повертати накопичене значення:
class OrderStats
{
public int $total = 0;
public int $count = 0;
}
$orders = collect([
['amount' => 100],
['amount' => 250],
['amount' => 50],
]);
$stats = $orders->reduceInto(new OrderStats, function (OrderStats $stats, array $order) {
$stats->total += $order['amount'];
$stats->count++;
});
$stats->total;
// 400
Коли зводите до скаляра або масиву, приймайте його в колбеку за посиланням, щоб ваші зміни застосувалися до початкового значення:
$collection = collect([1, 2, 3, 4, 5]);
$even = $collection->reduceInto([], function (array &$result, int $value) {
if ($value % 2 === 0) {
$result[] = $value;
}
});
// [2, 4]
reduceSpread() {.collection-method}
Метод reduceSpread зводить колекцію до масиву значень, передаючи результати кожної ітерації в наступну. Цей метод схожий на reduce, але приймає кілька початкових значень:
[$creditsRemaining, $batch] = Image::where('status', 'unprocessed')
->get()
->reduceSpread(function (int $creditsRemaining, Collection $batch, Image $image) {
if ($creditsRemaining >= $image->creditsRequired()) {
$batch->push($image);
$creditsRemaining -= $image->creditsRequired();
}
return [$creditsRemaining, $batch];
}, $creditsAvailable, collect());
reject() {.collection-method}
Метод reject фільтрує колекцію за допомогою заданого замикання. Замикання має повернути true, якщо елемент треба прибрати з результуючої колекції:
$collection = collect([1, 2, 3, 4]);
$filtered = $collection->reject(function (int $value, int $key) {
return $value > 2;
});
$filtered->all();
// [1, 2]
Протилежний до reject метод - filter.
replace() {.collection-method}
Метод replace поводиться подібно до merge; проте, окрім перезапису збіжних елементів із рядковими ключами, replace перезапише й елементи колекції зі збіжними числовими ключами:
$collection = collect(['Taylor', 'Abigail', 'James']);
$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);
$replaced->all();
// ['Taylor', 'Victoria', 'James', 'Finn']
replaceRecursive() {.collection-method}
Метод replaceRecursive поводиться подібно до replace, але заходить усередину масивів і застосовує той самий процес заміни до вкладених значень:
$collection = collect([
'Taylor',
'Abigail',
[
'James',
'Victoria',
'Finn'
]
]);
$replaced = $collection->replaceRecursive([
'Charlie',
2 => [1 => 'King']
]);
$replaced->all();
// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]
reverse() {.collection-method}
Метод reverse змінює порядок елементів колекції на зворотний, зберігаючи початкові ключі:
$collection = collect(['a', 'b', 'c', 'd', 'e']);
$reversed = $collection->reverse();
$reversed->all();
/*
[
4 => 'e',
3 => 'd',
2 => 'c',
1 => 'b',
0 => 'a',
]
*/
search() {.collection-method}
Метод 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 (int $item, int $key) {
return $item > 5;
});
// 2
select() {.collection-method}
Метод select вибирає з колекції задані ключі, подібно до SQL-виразу SELECT:
$users = collect([
['name' => 'Taylor Otwell', 'role' => 'Developer', 'status' => 'active'],
['name' => 'Victoria Faith', 'role' => 'Researcher', 'status' => 'active'],
]);
$users->select(['name', 'role']);
/*
[
['name' => 'Taylor Otwell', 'role' => 'Developer'],
['name' => 'Victoria Faith', 'role' => 'Researcher'],
],
*/
shift() {.collection-method}
Метод 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-method}
Метод shuffle випадково перемішує елементи колекції:
$collection = collect([1, 2, 3, 4, 5]);
$shuffled = $collection->shuffle();
$shuffled->all();
// [3, 2, 5, 1, 4] - (згенеровано випадково)
skip() {.collection-method}
Метод 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() {.collection-method}
Метод skipUntil пропускає елементи колекції, доки заданий колбек повертає false. Щойно колбек поверне true, усі решта елементів колекції повернуться у вигляді нової колекції:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipUntil(function (int $item) {
return $item >= 3;
});
$subset->all();
// [3, 4]
Методу skipUntil можна також передати просте значення, щоб пропустити всі елементи, доки не трапиться задане значення:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipUntil(3);
$subset->all();
// [3, 4]
[!WARNING] Якщо задане значення не знайдено або колбек ніколи не повертає
true, методskipUntilповерне порожню колекцію.
skipWhile() {.collection-method}
Метод skipWhile пропускає елементи колекції, доки заданий колбек повертає true. Щойно колбек поверне false, усі решта елементів колекції повернуться у вигляді нової колекції:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->skipWhile(function (int $item) {
return $item <= 3;
});
$subset->all();
// [4]
[!WARNING] Якщо колбек ніколи не повертає
false, методskipWhileповерне порожню колекцію.
slice() {.collection-method}
Метод 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, щоб переіндексувати їх.
sliding() {.collection-method}
Метод 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 (Collection $previous, Collection $current) {
$current->total = $previous->total + $current->amount;
});
Другим аргументом можна за бажанням передати "крок", який визначає відстань між першими елементами сусідніх чанків:
$collection = collect([1, 2, 3, 4, 5]);
$chunks = $collection->sliding(3, step: 2);
$chunks->toArray();
// [[1, 2, 3], [3, 4, 5]]
sole() {.collection-method}
Метод sole повертає перший елемент колекції, який проходить задану перевірку, але лише якщо перевірку проходить рівно один елемент:
collect([1, 2, 3, 4])->sole(function (int $value, int $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.
some() {.collection-method}
Псевдонім методу contains.
sort() {.collection-method}
Метод sort сортує колекцію. Відсортована колекція зберігає початкові ключі масиву, тож у прикладі нижче ми скористаємося методом values, щоб скинути ключі до послідовних числових індексів:
$collection = collect([5, 3, 1, 2, 4]);
$sorted = $collection->sort();
$sorted->values()->all();
// [1, 2, 3, 4, 5]
Якщо потреби в сортуванні складніші, можна передати в sort колбек із власним алгоритмом. Зверніться до документації PHP щодо uasort - саме її метод sort колекції використовує всередині.
[!NOTE] Якщо треба відсортувати колекцію вкладених масивів або обʼєктів, див. методи sortBy і sortByDesc.
sortBy() {.collection-method}
Метод 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],
]
*/
Другим аргументом метод sortBy приймає прапорці сортування:
$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 (array $product, int $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 (array $a, array $b) => $a['name'] <=> $b['name'],
fn (array $a, array $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],
]
*/
sortByDesc() {.collection-method}
Цей метод має ту саму сигнатуру, що й sortBy, але сортує колекцію у зворотному порядку.
sortDesc() {.collection-method}
Цей метод сортує колекцію у зворотному порядку відносно методу sort:
$collection = collect([5, 3, 1, 2, 4]);
$sorted = $collection->sortDesc();
$sorted->values()->all();
// [5, 4, 3, 2, 1]
На відміну від sort, у sortDesc не можна передати замикання. Натомість скористайтеся методом sort і інвертуйте своє порівняння.
sortKeys() {.collection-method}
Метод sortKeys сортує колекцію за ключами базового асоціативного масиву:
$collection = collect([
'id' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
$sorted = $collection->sortKeys();
$sorted->all();
/*
[
'first' => 'John',
'id' => 22345,
'last' => 'Doe',
]
*/
sortKeysDesc() {.collection-method}
Цей метод має ту саму сигнатуру, що й sortKeys, але сортує колекцію у зворотному порядку.
sortKeysUsing() {.collection-method}
Метод sortKeysUsing сортує колекцію за ключами базового асоціативного масиву за допомогою колбека:
$collection = collect([
'ID' => 22345,
'first' => 'John',
'last' => 'Doe',
]);
$sorted = $collection->sortKeysUsing('strnatcasecmp');
$sorted->all();
/*
[
'first' => 'John',
'ID' => 22345,
'last' => 'Doe',
]
*/
Колбек має бути функцією порівняння, яка повертає ціле число менше нуля, рівне нулю або більше нуля. Докладніше в документації PHP щодо uksort - саме цю PHP-функцію метод sortKeysUsing використовує всередині.
splice() {.collection-method}
Метод 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-method}
Метод split розбиває колекцію на задану кількість груп:
$collection = collect([1, 2, 3, 4, 5]);
$groups = $collection->split(3);
$groups->all();
// [[1, 2], [3, 4], [5]]
splitIn() {.collection-method}
Метод 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() {.collection-method}
Метод 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 (array $product) {
return count($product['colors']);
});
// 6
take() {.collection-method}
Метод 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() {.collection-method}
Метод takeUntil повертає елементи колекції, доки заданий колбек не поверне true:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeUntil(function (int $item) {
return $item >= 3;
});
$subset->all();
// [1, 2]
Методу takeUntil можна також передати просте значення, щоб отримати елементи до того, як трапиться задане значення:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeUntil(3);
$subset->all();
// [1, 2]
[!WARNING] Якщо задане значення не знайдено або колбек ніколи не повертає
true, методtakeUntilповерне всі елементи колекції.
takeWhile() {.collection-method}
Метод takeWhile повертає елементи колекції, доки заданий колбек не поверне false:
$collection = collect([1, 2, 3, 4]);
$subset = $collection->takeWhile(function (int $item) {
return $item < 3;
});
$subset->all();
// [1, 2]
[!WARNING] Якщо колбек ніколи не повертає
false, методtakeWhileповерне всі елементи колекції.
tap() {.collection-method}
Метод tap передає колекцію в заданий колбек, даючи змогу "підключитися" до колекції в конкретній точці і щось зробити з елементами, не впливаючи на саму колекцію. Далі метод tap повертає колекцію:
collect([2, 4, 3, 1, 5])
->sort()
->tap(function (Collection $collection) {
Log::debug('Values after sorting', $collection->values()->all());
})
->shift();
// 1
times() {.collection-method}
Статичний метод times створює нову колекцію, викликаючи задане замикання вказану кількість разів:
$collection = Collection::times(10, function (int $number) {
return $number * 9;
});
$collection->all();
// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
toArray() {.collection-method}
Метод toArray перетворює колекцію на звичайний PHP-array. Якщо значення колекції - це моделі Eloquent, вони також будуть перетворені на масиви:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toArray();
/*
[
['name' => 'Desk', 'price' => 200],
]
*/
[!WARNING]
toArrayперетворює на масив і всі вкладені обʼєкти колекції, які є екземплярамиArrayable. Якщо потрібен сирий масив, що лежить в основі колекції, скористайтеся методом all.
toJson() {.collection-method}
Метод toJson перетворює колекцію на серіалізований JSON-рядок:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toJson();
// '{"name":"Desk", "price":200}'
toPrettyJson() {.collection-method}
Метод toPrettyJson перетворює колекцію на відформатований JSON-рядок з опцією JSON_PRETTY_PRINT:
$collection = collect(['name' => 'Desk', 'price' => 200]);
$collection->toPrettyJson();
transform() {.collection-method}
Метод transform проходить колекцію і викликає заданий колбек для кожного елемента колекції. Елементи колекції замінюються значеннями, які повернув колбек:
$collection = collect([1, 2, 3, 4, 5]);
$collection->transform(function (int $item, int $key) {
return $item * 2;
});
$collection->all();
// [2, 4, 6, 8, 10]
[!WARNING] На відміну від більшості інших методів колекції,
transformзмінює саму колекцію. Якщо натомість треба створити нову колекцію, скористайтеся методом map.
undot() {.collection-method}
Метод undot розгортає одновимірну колекцію з "крапковою" нотацією в багатовимірну:
$person = collect([
'name.first_name' => 'Marie',
'name.last_name' => 'Valentine',
'address.line_1' => '2992 Eagle Drive',
'address.line_2' => '',
'address.suburb' => 'Detroit',
'address.state' => 'MI',
'address.postcode' => '48219'
]);
$person = $person->undot();
$person->toArray();
/*
[
"name" => [
"first_name" => "Marie",
"last_name" => "Valentine",
],
"address" => [
"line_1" => "2992 Eagle Drive",
"line_2" => "",
"suburb" => "Detroit",
"state" => "MI",
"postcode" => "48219",
],
]
*/
union() {.collection-method}
Метод union додає заданий масив до колекції. Якщо переданий масив містить ключі, які вже є в початковій колекції, перевага надається значенням початкової колекції:
$collection = collect([1 => ['a'], 2 => ['b']]);
$union = $collection->union([3 => ['c'], 1 => ['d']]);
$union->all();
// [1 => ['a'], 2 => ['b'], 3 => ['c']]
unique() {.collection-method}
Метод 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 (array $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.
[!NOTE] Поведінка цього методу змінюється при роботі з колекціями Eloquent.
uniqueStrict() {.collection-method}
Цей метод має ту саму сигнатуру, що й unique, але всі значення порівнюються «строго».
unless() {.collection-method}
Метод unless виконає переданий колбек, якщо перший аргумент методу не дорівнює true. У замикання передаються екземпляр колекції та перший аргумент, переданий методу unless:
$collection = collect([1, 2, 3]);
$collection->unless(true, function (Collection $collection, bool $value) {
return $collection->push(4);
});
$collection->unless(false, function (Collection $collection, bool $value) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]
Методу unless можна передати другий колбек. Він виконається тоді, коли перший аргумент методу unless дорівнює true:
$collection = collect([1, 2, 3]);
$collection->unless(true, function (Collection $collection, bool $value) {
return $collection->push(4);
}, function (Collection $collection, bool $value) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]
Протилежний до unless метод описано в розділі when.
unlessEmpty() {.collection-method}
Псевдонім методу whenNotEmpty.
unlessNotEmpty() {.collection-method}
Псевдонім методу whenEmpty.
unwrap() {.collection-method}
Статичний метод unwrap повертає з переданого значення елементи колекції, якщо це можливо:
Collection::unwrap(collect('John Doe'));
// ['John Doe']
Collection::unwrap(['John Doe']);
// ['John Doe']
Collection::unwrap('John Doe');
// 'John Doe'
value() {.collection-method}
Метод value дістає задане значення з першого елемента колекції:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Speaker', 'price' => 400],
]);
$value = $collection->value('price');
// 200
values() {.collection-method}
Метод values повертає нову колекцію, ключі якої скинуто до послідовних цілих чисел:
$collection = collect([
10 => ['product' => 'Desk', 'price' => 200],
11 => ['product' => 'Speaker', 'price' => 400],
]);
$values = $collection->values();
$values->all();
/*
[
0 => ['product' => 'Desk', 'price' => 200],
1 => ['product' => 'Speaker', 'price' => 400],
]
*/
when() {.collection-method}
Метод when виконає переданий колбек, якщо перший аргумент методу дорівнює true. У замикання передаються екземпляр колекції та перший аргумент, переданий методу when:
$collection = collect([1, 2, 3]);
$collection->when(true, function (Collection $collection, bool $value) {
return $collection->push(4);
});
$collection->when(false, function (Collection $collection, bool $value) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 4]
Методу when можна передати другий колбек. Він виконається тоді, коли перший аргумент методу when дорівнює false:
$collection = collect([1, 2, 3]);
$collection->when(false, function (Collection $collection, bool $value) {
return $collection->push(4);
}, function (Collection $collection, bool $value) {
return $collection->push(5);
});
$collection->all();
// [1, 2, 3, 5]
Протилежний до when метод описано в розділі unless.
whenEmpty() {.collection-method}
Метод whenEmpty виконає переданий колбек, коли колекція порожня:
$collection = collect(['Michael', 'Tom']);
$collection->whenEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Michael', 'Tom']
$collection = collect();
$collection->whenEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Adam']
Методу whenEmpty можна передати друге замикання, яке виконається, коли колекція не порожня:
$collection = collect(['Michael', 'Tom']);
$collection->whenEmpty(function (Collection $collection) {
return $collection->push('Adam');
}, function (Collection $collection) {
return $collection->push('Taylor');
});
$collection->all();
// ['Michael', 'Tom', 'Taylor']
Протилежний до whenEmpty метод описано в розділі whenNotEmpty.
whenNotEmpty() {.collection-method}
Метод whenNotEmpty виконає переданий колбек, коли колекція не порожня:
$collection = collect(['Michael', 'Tom']);
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// ['Michael', 'Tom', 'Adam']
$collection = collect();
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('Adam');
});
$collection->all();
// []
Методу whenNotEmpty можна передати друге замикання, яке виконається, коли колекція порожня:
$collection = collect();
$collection->whenNotEmpty(function (Collection $collection) {
return $collection->push('Adam');
}, function (Collection $collection) {
return $collection->push('Taylor');
});
$collection->all();
// ['Taylor']
Протилежний до whenNotEmpty метод описано в розділі whenEmpty.
where() {.collection-method}
Метод 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, а для пошуку значень null - методи whereNull і whereNotNull.
За бажання другим параметром можна передати оператор порівняння. Підтримуються оператори: '===', '!==', '!=', '==', '=', '<>', '>', '<', '>=' і '<=':
$collection = collect([
['name' => 'Jim', 'platform' => 'Mac'],
['name' => 'Sally', 'platform' => 'Mac'],
['name' => 'Sue', 'platform' => 'Linux'],
]);
$filtered = $collection->where('platform', '!=', 'Linux');
$filtered->all();
/*
[
['name' => 'Jim', 'platform' => 'Mac'],
['name' => 'Sally', 'platform' => 'Mac'],
]
*/
whereStrict() {.collection-method}
Цей метод має ту саму сигнатуру, що й where, але всі значення порівнюються «строго».
whereBetween() {.collection-method}
Метод 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-method}
Метод 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.
whereInStrict() {.collection-method}
Цей метод має ту саму сигнатуру, що й whereIn, але всі значення порівнюються «строго».
whereInstanceOf() {.collection-method}
Метод 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-method}
Метод 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-method}
Метод 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.
whereNotInStrict() {.collection-method}
Цей метод має ту саму сигнатуру, що й whereNotIn, але всі значення порівнюються «строго».
whereNotNull() {.collection-method}
Метод whereNotNull повертає елементи колекції, у яких заданий ключ не дорівнює null:
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
['name' => 0],
['name' => ''],
]);
$filtered = $collection->whereNotNull('name');
$filtered->all();
/*
[
['name' => 'Desk'],
['name' => 'Bookcase'],
['name' => 0],
['name' => ''],
]
*/
whereNull() {.collection-method}
Метод whereNull повертає елементи колекції, у яких заданий ключ дорівнює null:
$collection = collect([
['name' => 'Desk'],
['name' => null],
['name' => 'Bookcase'],
['name' => 0],
['name' => ''],
]);
$filtered = $collection->whereNull('name');
$filtered->all();
/*
[
['name' => null],
]
*/
wrap() {.collection-method}
Статичний метод 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-method}
Метод zip обʼєднує значення заданого масиву зі значеннями вихідної колекції за відповідними індексами:
$collection = collect(['Chair', 'Desk']);
$zipped = $collection->zip([100, 200]);
$zipped->all();
// [['Chair', 100], ['Desk', 200]]
Повідомлення вищого порядку
Колекції також підтримують «повідомлення вищого порядку» (higher order messages) - скорочення для типових дій над колекціями. Повідомлення вищого порядку надають такі методи колекцій: 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;
Ліниві колекції
Вступ
[!WARNING] Перш ніж заглиблюватись у ліниві колекції 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;
}
fclose($handle);
})->chunk(4)->map(function (array $lines) {
return LogEntry::fromLines($lines);
})->each(function (LogEntry $logEntry) {
// Обробляємо запис логу...
});
Або уявіть, що треба пройтися по 10 000 моделях Eloquent. Зі звичайними колекціями Laravel усі 10 000 моделей Eloquent мають бути завантажені в памʼять одночасно:
use App\Models\User;
$users = User::all()->filter(function (User $user) {
return $user->id > 500;
});
Проте метод cursor конструктора запитів повертає екземпляр LazyCollection. Це дозволяє виконати до бази один-єдиний запит і водночас тримати в памʼяті лише одну модель Eloquent за раз. У цьому прикладі колбек filter не виконується, доки ми справді не переберемо кожного користувача окремо, що різко зменшує споживання памʼяті:
use App\Models\User;
$users = User::cursor()->filter(function (User $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;
}
fclose($handle);
});
Контракт Enumerable
Майже всі методи класу Collection доступні й у класі LazyCollection. Обидва ці класи реалізують контракт Illuminate\Support\Enumerable, який визначає такі методи:
all average avg chunk chunkBy chunkWhile collapse collect combine concat contains containsStrict count countBy crossJoin dd diff diffAssoc diffKeys dump duplicates duplicatesStrict each eachSpread every except filter first firstOrFail firstWhere flatMap flatten flip forPage get groupBy has implode intersect intersectAssoc 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 reduceInto reject replace replaceRecursive reverse search shuffle skip slice sole 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
[!WARNING] Методи, які змінюють колекцію (як-от
shift,pop,prependтощо), у класіLazyCollectionнедоступні.
Методи лінивих колекцій
Окрім методів, визначених у контракті Enumerable, клас LazyCollection містить такі методи:
takeUntilTimeout() {.collection-method}
Метод takeUntilTimeout повертає нову ліниву колекцію, яка перебиратиме значення до вказаного моменту часу. Після цього моменту перебір припиняється:
$lazyCollection = LazyCollection::times(INF)
->takeUntilTimeout(now()->plus(minutes: 1));
$lazyCollection->each(function (int $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) => $invoice->submit());
tapEach() {.collection-method}
Метод each викликає переданий колбек для кожного елемента колекції одразу, а tapEach викликає його лише тоді, коли елементи по одному витягуються зі списку:
// Поки що нічого не виведено...
$lazyCollection = LazyCollection::times(INF)->tapEach(function (int $value) {
dump($value);
});
// Виведено три елементи...
$array = $lazyCollection->take(3)->all();
// 1
// 2
// 3
throttle() {.collection-method}
Метод throttle обмежує швидкість лінивої колекції так, що кожне значення повертається через вказану кількість секунд. Це особливо корисно, коли ви працюєте із зовнішніми API, які обмежують частоту вхідних запитів:
use App\Models\User;
User::where('vip', true)
->cursor()
->throttle(seconds: 1)
->each(function (User $user) {
// Викликаємо зовнішній API...
});
remember() {.collection-method}
Метод remember повертає нову ліниву колекцію, яка запамʼятає вже перебрані значення й не діставатиме їх знову під час наступних перебирань колекції:
// Жодного запиту ще не виконано...
$users = User::cursor()->remember();
// Запит виконується...
// Перші 5 користувачів створюються з даних бази...
$users->take(5)->all();
// Перші 5 користувачів беруться з кешу колекції...
// Решта створюється з даних бази...
$users->take(20)->all();
withHeartbeat() {.collection-method}
Метод withHeartbeat дозволяє виконувати колбек через рівні проміжки часу, поки триває перебір лінивої колекції. Це стає в пригоді для довготривалих операцій, яким потрібні періодичні службові дії, як-от продовження блокувань чи надсилання оновлень прогресу:
use Carbon\CarbonInterval;
use Illuminate\Support\Facades\Cache;
$lock = Cache::lock('generate-reports', seconds: 60 * 5);
if ($lock->get()) {
try {
Report::where('status', 'pending')
->lazy()
->withHeartbeat(
CarbonInterval::minutes(4),
fn () => $lock->extend(CarbonInterval::minutes(5))
)
->each(fn ($report) => $report->process());
} finally {
$lock->release();
}
}
Перекладаємо з офіційної документації, розділ за розділом, і не ховаємо недоперекладене. Помітили неточність у терміні чи реченні: напишіть, виправимо.