Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Статті за тегом «Collections»

Статті, новини, туторіали та переклади від учасників спільноти

No results.
Tips 11 вересня 2026

sortBy() з кількома колонками

Потрібно сортувати за кількома полями? Подібно до ORDER BY у SQL.

sortBy() приймає масив пар "колонка/напрям".

Синтаксис:

Масив масивів: [column, direction].

Напрям:

asc або desc.

Порада: використовуйте sortByDesc() для одного поля зі спаданням.

$users = collect([
  ['name' => 'John', 'age' => 30, 'city' => 'NYC'],
  ['name' => 'Jane', 'age' => 25, 'city' => 'LA'],
  ['name' => 'Bob', 'age' => 30, 'city' => 'SF'],
]);

// Сортування за віком, потім за ім'ям
$sorted = $users->sortBy([
  ['age', 'asc'],
  ['name', 'asc'],
]);

// За містом спаданням, далі за віком
$sorted = $users->sortBy([
  ['city', 'desc'],
  ['age', 'asc'],
]);

// З callback
$sorted = $users->sortBy([
  [fn($user) => $user['age'], 'desc'],
  ['name', 'asc'],
]);

// Еloquent-колекції
$posts = Post::all()->sortBy([
  ['featured', 'desc'],
  ['published_at', 'desc'],
]);
// Вкладений атрибут
$orders = Order::with('customer')->get()->sortBy([
  ['customer.name', 'asc'],
  ['total', 'desc'],
]);

// Скинути ключі
$sorted->values();

// Одне поле - спаданням
$users->sortByDesc('age');

// Збереження ключів
$users->sortBy('age'); // Залишає ключі
$users->sortBy('age')->values(); // Перегенерує ключі

// Складне сортування з пріоритетами
$tasks = collect($tasks)->sortBy([
  ['priority', 'desc'],
  ['due_date', 'asc'],
  ['created_at', 'asc'],
]);

// Сортування товарів за рейтингом і ціною
$products = Product::all()->sortBy([
  ['rating', 'desc'],
  ['price', 'asc'],
])->values();
Tips 09 вересня 2026

whenEmpty() та whenNotEmpty() - умовні операції

Потрібно виконувати код лише тоді, коли колекція порожня або непорожня? if/else роблять код об'ємним.

whenEmpty() та whenNotEmpty() роблять це чисто.

Приклади використання:

  • Показати контент за замовчуванням
  • Логувати попередження
  • Запускати fallback-логіку
  • Присвоювати значення за замовчуванням

Перевага:

Методи ланцюжаться та зберігають fluent-синтаксис.

Порада: значення, повернуте з callback, стає новим значенням колекції.

3
$users = User::where('active', true)->get();

// ПОГАНО: розривається ланцюжок
if ($users->isEmpty()) {
  return redirect()->back()->with('error', 'No active users');
}

// ДОБРЕ: fluent-синтаксис
$users->whenEmpty(function () {
  return redirect()->back()->with('error', 'No active users');
});

// Додати елементи за замовчуванням, якщо порожньо
$products = Product::where('featured', true)->get();

$products = $products->whenEmpty(function ($collection) {
  return Product::latest()->limit(5)->get();
});

// Логування, якщо непорожня
$errors->whenNotEmpty(function ($collection) {
  Log::error('Validation errors found', $collection->toArray());
});

// З "else"
$users->whenEmpty(
  fn($collection) => ['name' => 'Guest'],
  fn($collection) => $collection->first()
);
// API-відповідь із fallback
return response()->json([
  'users' => $users->whenEmpty(fn() => collect([
    ['name' => 'No users found', 'id' => null]
  ]))
]);

// Ланцюжок операцій
$results = collect($searchResults)
  ->whenEmpty(fn() => $this->getDefaultResults())
  ->take(10)
  ->map(fn($item) => $this->format($item));

// Прогрів кешу
$cached = Cache::get('popular_posts');

collect($cached)->whenEmpty(function () {
  $posts = Post::popular()->get();
  Cache::put('popular_posts', $posts, 3600);
  return $posts;
});

// Надсилання email-дайджесту
$notifications->whenNotEmpty(function ($items) {
  Mail::to($user)->send(new NotificationDigest($items));
});
Tips 07 вересня 2026

firstWhere() - Пошук елемента за атрибутом

Потрібно знайти перший елемент, що відповідає умові?

firstWhere() виглядає чистіше, ніж filter()->first().

Переваги:

  • Один метод замість двох
  • Автоматична обробка null
  • Підтримує оператори

Оператори:

Такі ж, як у where(): =, !=, >, <, >=, <=

Порада: використовуйте другий параметр для значення за замовчуванням, якщо елемент не знайдено.

3
$users = collect([
  ['id' => 1, 'name' => 'John', 'age' => 25],
  ['id' => 2, 'name' => 'Jane', 'age' => 30],
  ['id' => 3, 'name' => 'Bob', 'age' => 35],
]);

// ПОГАНО: два методи
$user = $users->filter(fn($u) => $u['age'] > 30)->first();

// ДОБРЕ: один метод
$user = $users->firstWhere('age', '>', 30);
// ['id' => 3, 'name' => 'Bob', 'age' => 35]

// Точна відповідність (оператор за замовчуванням - =)
$user = $users->firstWhere('name', 'Jane');

// Із значенням за замовчуванням
$guest = ['name' => 'Guest'];
$user = $users->firstWhere('age', '>', 100) ?? $guest;

// Eloquent-колекції
$featured = Post::all()->firstWhere('featured', true);

// Кілька умов - first із callback
$user = $users->first(
  fn($u) => $u['age'] > 30 && $u['name'] !== 'Bob'
);
Tips 04 вересня 2026

unique() - інтелектуальне видалення дублікатів

Є дублікати email? Перевіряти вручну необов'язково.

unique() видаляє дублікати.

Як працює:

Залишає перше значення, інші прибирає.

Розширення:

  • Унікальність за ключем
  • Унікальність за callback
  • Строге порівняння

Порада: uniqueStrict() враховує тип (1 !== "1").

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

// За ключем
$users = collect([
  ['id' => 1, 'email' => 'john@example.com'],
  ['id' => 2, 'email' => 'jane@example.com'],
  ['id' => 3, 'email' => 'john@example.com'],
]);

$uniqueByEmail = $users->unique('email');

// За callback
$products = collect([
  ['name' => 'iPhone', 'price' => 999],
  ['name' => 'Samsung', 'price' => 999],
  ['name' => 'iPad', 'price' => 799],
]);

$uniqueByPrice = $products->unique(fn($i) => $i['price']);

// Строге порівняння
collect([1, '1', 2, '2'])->unique();       // [1, 2]
collect([1, '1', 2, '2'])->uniqueStrict(); // [1, '1', 2, '2']

// Скинути ключі
$unique->values();
Tips 02 вересня 2026

lazy() - колекції без перевантаження пам'яті

Якщо обробляється 50 000 елементів і застосовується 10 методів, звичайна колекція створить 10 копій у пам'яті.

Lazy колекції обробляють один елемент за раз.

Як працює:

Елемент проходить через усі методи і лише потім переходить до наступного.

Коли варто використовувати:

  • Великі файли
  • Стрімінг
  • Генератори
  • Обмежена пам'ять

Порада: перетворити назад у звичайну колекцію - all().

// Погано: багато копій у пам'яті
$result = collect($hugeArray)
  ->filter(...)
  ->map(...)
  ->sortBy(...)
  ->take(100);

// Добре: один елемент за раз
$result = collect($hugeArray)
  ->lazy()
  ->filter(...)
  ->map(...)
  ->sortBy(...)
  ->take(100)
  ->all();

// Великий CSV
$users = LazyCollection::make(function () {
  $h = fopen('users.csv', 'r');
  while ($line = fgets($h)) {
    yield $line;
  }
  fclose($h);
})->map(fn($l) => str_getcsv($l));

// cursor() - вже lazy
User::cursor();
Tips 31 серпня 2026

tap() - дебаг без зміни ланцюжка

Потрібно подивитися стан колекції в середині ланцюга?

tap() дозволяє "підглянути" в колекцію, не змінюючи її.

Як працює:

Callback отримує колекцію, але повернуте значення ігнорується.

Сценарії:

  • Дебаг
  • Логування
  • Побічні ефекти

Різниця з pipe():

  • pipe() використовує значення, яке повернув callback
  • tap() ігнорує і продовжує з оригіналом
5
$result = $users
  ->where('active', true)
  ->tap(fn($c) => logger("Active: {$c->count()}"))
  ->where('role', 'admin')
  ->tap(fn($c) => logger("Admins: {$c->count()}"))
  ->get();

// Порівняння
$collection->pipe(fn($c) => $c->count()); // повертає число
$collection->tap(fn($c) => $c->count()); // повертає колекцію
Tips 28 серпня 2026

pipe() - кастомна логіка у ланцюжку

Потрібно застосувати складну логіку до всієї колекції?

pipe() передає в callback усю колекцію і повертає те, що callback повернув.

Переваги:

  • Гнучка логіка
  • Розбиття складних ланцюжків
  • Умовні трансформації
  • Дебаг

Різниця з map():

  • map() - елемент за елементом
  • pipe() - вся колекція одразу

Порада: використовувати іменовані функції для читабельності.

5
$result = $users
  ->where('active', true)
  ->pipe(fn($c) => $c->sortBy('last_login')->take(10))
  ->values();

// Умовне сортування
$posts = Post::all()->pipe(function ($posts) use ($request) {
  return $request->sort === 'popular'
    ? $posts->sortByDesc('views')
    : $posts->sortByDesc('created_at');
});

// Дебаг
$result = $users
  ->where('active', true)
  ->pipe(fn($c) => tap($c, fn($c) => logger($c->count())))
  ->where('role', 'admin');
Tips 26 серпня 2026

partition() - поділ колекції на дві частини

Потрібно поділити користувачів на активних і неактивних?

partition() повертає одразу дві групи.

Різниця з filter():

  • filter() повертає лише truthy
  • partition() повертає truthy і falsy одразу

Сценарії:

  • Валідні / невалідні дані
  • Passed / failed
  • Approved / pending

Порада: зручно для різних обробок двох груп.

6
[$active, $inactive] = $users->partition(fn($u) => $u->active);

// Дві різні обробки
$active->each(fn($u) => ...);
$inactive->each(fn($u) => ...);

// Валідація
[$valid, $invalid] = $orders->partition(fn($o) =>
  $o->total > 0 && $o->email !== null
);

// Студенти
[$passed, $failed] = $students->partition(
  fn($s) => $s->score >= 60
);
Tips 24 серпня 2026

groupBy() - організація даних як у таблиці

Потрібно показати пости за категоріями? Вкладені цикли не потрібні.

groupBy() групує колекцію за ключем.

Як працює:

Повертає масив груп, де кожна група - окрема колекція.

Розширені можливості:

  • Групування за callback
  • Кілька рівнів групування
  • Dot notation

Порада: ідеально для аналітики, звітів і категоризації.

// Групування за категорією
$byCategory = $posts->groupBy('category_id');

// Групування за роком
$byYear = $posts->groupBy(fn($p) => $p->created_at->year);

// Доступ до груп
foreach ($byCategory as $categoryId => $posts) {
  echo "Category {$categoryId}: {$posts->count()} posts\n";
}

// Кілька рівнів
$byYearMonth = $posts->groupBy([
  fn($p) => $p->created_at->year,
  fn($p) => $p->created_at->month,
]);

// Групування по зв'язку
$byPostTitle = $comments->groupBy('post.title');

// Практичний приклад - суми продажів
$report = $orders->groupBy('status')
  ->map(fn($group) => $group->sum('total'));

Матеріали за темою «Collections»: усе, що ми писали про це українською. Нижче - суміжні теми, якщо шукаєте ширше.

Зараз опубліковано 15 матеріалів від 3 авторів. Останній матеріал - 11 вересня 2026.