Увійти Реєстрація
Вакансії
Вакансії Laravel Компанії Статистика
Підготовка
Як підготуватися < href="https://laravelukraine.com/interviews" wire:navigate.hover class="flex items-center gap-3 rounded-md px-3 py-2 text-base font-medium text-gray-600 hover:bg-gray-50 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-900 dark:hover:text-white" >Співбесіди Тестування Документація
Блог
Всі статті Серії
Екосистема
Пакети Ресурси Проєкти Інструменти Події Відео
Інше
Про нас Реклама

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

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

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

diff() і diffKeys() - пошук відмінностей

Порівнюєте колекції? Потрібно знайти, що додалось або зникло?

diff() порівнює значення, diffKeys() - ключі.

Методи:

  • diff() - порівняння за значеннями
  • diffKeys() - за ключами
  • diffAssoc() - за ключем і значенням

Порада: ідеально, щоб визначити, які дані змінилися між двома наборами.

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

$removed = $original->diff($updated); // [4, 5]
$added   = $updated->diff($original); // [6, 7]

// diffKeys
$old = collect(['a' => 1, 'b' => 2, 'c' => 3]);
$new = collect(['a' => 1, 'b' => 5, 'd' => 4]);

$keyDiff = $old->diffKeys($new);
// ['c' => 3]

// diffAssoc
$assocDiff = $old->diffAssoc($new);
// ['b' => 2, 'c' => 3]

// Виявлення змін у формі
$originalData = collect($user->toArray());
$updatedData  = collect($request->validated());

$changes = $updatedData->diffAssoc($originalData);

if ($changes->isNotEmpty()) {
  $user->update($changes->toArray());
  Log::info('User updated', ['changes' => $changes]);
}
Tips 25 вересня 2026

countBy() - підрахунок за групами

Потрібно порахувати елементи за категоріями?

countBy() групує та одразу рахує.

Використання:

  • Підрахунок за статусом
  • Групування за категорією
  • Частотний аналіз
  • Статистика

Результат:

Колекція, де ключ - група, значення - кількість.

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

$orders = collect([
  ['status' => 'pending'],
  ['status' => 'completed'],
  ['status' => 'pending'],
  ['status' => 'cancelled'],
  ['status' => 'completed'],
  ['status' => 'completed'],
]);

$counts = $orders->countBy('status');
// ['pending' => 2, 'completed' => 3, 'cancelled' => 1]

// Callback
$users = User::all();

$byAge = $users->countBy(fn($u) => floor($u->age / 10) * 10);
// [20 => X, 30 => Y, 40 => Z]

// Email-домени
$emails = collect([
  'john@gmail.com',
  'jane@yahoo.com',
  'bob@gmail.com',
  'alice@gmail.com',
]);

$domains = $emails->countBy(
  fn($e) => explode('@', $e)[1]
);
// ['gmail.com' => 3, 'yahoo.com' => 1]
// Розподіл за довжиною рядка
$words = collect(['hello', 'world', 'php', 'laravel', 'code']);

$lengths = $words->countBy(fn($word) => strlen($word));

// Статистика для dashboard
public function stats()
{
  $orders = Order::whereDate('created_at', today())->get();

  return [
    'by_status' => $orders->countBy('status'),
    'by_payment' => $orders->countBy('payment_method'),
    'by_hour' => $orders->countBy(
      fn($o) => $o->created_at->hour
    ),
  ];
}
Tips 23 вересня 2026

collect() - колекції будь-де

Працюєте з масивами? Перетворіть їх на колекції одним викликом.

collect() обгортає масив у Collection.

Переваги:

  • Fluent-синтаксис
  • Доступ до всіх методів колекцій
  • Використання в будь-яких шарах застосунку

Порада: застосовуйте collect() до масивів з Request для зручного фільтрування.

// Масив → колекція
$data = collect([1, 2, 3, 4, 5]);

$result = $data->filter(fn($n) => $n > 2)
  ->map(fn($n) => $n * 2)
  ->sum();

// Обробка request-даних
public function store(Request $request)
{
  $tags = collect($request->tags)
    ->filter()
    ->unique()
    ->values()
    ->toArray();

  Post::create([
    'title' => $request->title,
    'tags' => $tags,
  ]);
}

// Конфігураційні масиви
$activeModules = collect(config('modules'))
  ->filter(fn($module) => $module['enabled'])
  ->pluck('name')
  ->toArray();
// API-відповідь
$apiData = Http::get('api/users')->json();

$users = collect($apiData['users'])
  ->map(fn($user) => [
    'id' => $user['id'],
    'name' => $user['first_name'] . ' ' . $user['last_name'],
    'email' => $user['email'],
  ])
  ->filter(fn($user) => $user['email'])
  ->values();

// Робота з файлами
$lines = collect(file('data.txt'))
  ->map(fn($line) => trim($line))
  ->filter()
  ->unique();
Tips 21 вересня 2026

zip() і combine() - зшивання колекцій

Маєте два окремі масиви - заголовки й значення? Або назви колонок і рядок CSV?

Зшивати їх циклом по індексу не потрібно.

Різниця:

  • zip() - склеює елементи попарно, повертає колекцію пар
  • combine() - бере першу колекцію як ключі, другу як значення

Де корисно:

  • Парсинг CSV: рядок заголовків + рядки даних
  • Зіставлення результатів двох запитів
  • Побудова асоціативних структур на льоту

Порада: zip() не обрізає до найкоротшої колекції - відсутні значення стають null.

// combine() - ключі + значення
$headers = collect(['name', 'email', 'age']);
$row = ['John', 'john@ex.com', 30];

$user = $headers->combine($row);
// ['name' => 'John', 'email' => 'john@ex.com', 'age' => 30]

// zip() - попарне склеювання
$names = collect(['John', 'Jane']);
$ages = [30, 25];

$pairs = $names->zip($ages);
// [['John', 30], ['Jane', 25]]

// zip() з нерівною довжиною - null у хвості
collect([1, 2, 3])->zip([10, 20]);
// [[1, 10], [2, 20], [3, null]]

// Кілька колекцій одночасно
$names->zip($ages, $emails);
// [['John', 30, 'john@ex.com'], ...]
// Парсинг CSV одним ланцюжком
$lines = collect(file('users.csv'));
$headers = str_getcsv($lines->shift());

$users = $lines->map(fn ($line) =>
  collect($headers)->combine(str_getcsv($line))
);
// $users[0]['email'] - асоціативний доступ

// Зіставлення двох запитів у мапу
$map = Order::pluck('id')
  ->combine(Order::pluck('total'));
// [1 => 250.00, 2 => 130.50]
Tips 18 вересня 2026

skip() і take() - пагінація без БД

Потрібна пагінація на клієнтській стороні або на вже завантажених даних?

skip() і take() працюють як OFFSET і LIMIT.

Використання:

  • In-memory пагінація
  • Розбиття результатів
  • API-слайси

Комбінація:

Використовуються разом.

Порада: forPage() - короткий шлях для skip/take.

$items = collect(range(1, 100));

// Пропустити 20, взяти 10
$page = $items->skip(20)->take(10);
// [21, 22, ..., 30]

// Пагінація вручну
$perPage = 10;
$page = 3;

$results = $items->skip(($page - 1) * $perPage)
  ->take($perPage);

// Коротко: forPage()
$results = $items->forPage(3, 10);

// Умовні варіанти замість числа
$items->skipUntil(fn($i) => $i > 50);
$items->skipWhile(fn($i) => $i < 20);
$items->takeUntil(fn($i) => $i > 50);
$items->takeWhile(fn($i) => $i < 20);
// API-пагінація на закешованих даних
public function index(Request $request)
{
  $all = Cache::remember(
    'products', 3600, fn () => Product::all()
  );

  $page = (int) $request->query('page', 1);
  $perPage = (int) $request->query('per_page', 15);

  return response()->json([
    'data' => $all->forPage($page, $perPage)->values(),
    'current_page' => $page,
    'per_page' => $perPage,
    'total' => $all->count(),
  ]);
}
Tips 16 вересня 2026

sliding() - Створення "ковзних вікон"

Потрібні перекривні чанки? Наприклад, для ковзного середнього?

sliding() створює ковзні вікна по колекції.

Використання:

  • Ковзні середні
  • Аналіз трендів
  • Пошук патернів
  • Послідовний аналіз

Параметри:

  • Розмір вікна
  • Крок (за замовчуванням 1)

Порада: підходить для аналізу часових рядів.

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

// Розмір 3, крок 1
$windows = $numbers->sliding(3);
// [[1,2,3], [2,3,4], [3,4,5], [4,5,6]]

// Розмір 3, крок 2
$windows = $numbers->sliding(3, 2);
// [[1,2,3], [3,4,5]]

// Ковзне середнє
$values = collect([10, 20, 30, 40, 50]);

$movingAvg = $values->sliding(3)
  ->map(fn($window) => $window->avg());
// [20, 30, 40]
// Аналіз трендів
$prices = collect([100, 105, 103, 110, 115, 112]);

$trends = $prices->sliding(3)
  ->map(fn($w) => [
    'start' => $w->first(),
    'end' => $w->last(),
    'trend' => $w->last() > $w->first() ? 'up' : 'down',
  ]);

// Порівняння сусідніх значень
$changes = $logs->sliding(2)->map(fn($pair) =>
  $pair->last()->value - $pair->first()->value
);

// Пошук послідовностей
$data = collect([1, 2, 3, 5, 6, 7]);

$seq = $data->sliding(2)
  ->filter(fn($p) => $p->last() - $p->first() === 1);
Tips 14 вересня 2026

collapse() - Сплющення вкладених колекцій

Маєте масив масивів? Потрібен один суцільний?

collapse() сплющує лише один рівень.

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

  • Об'єднання кількох колекцій
  • Сплющення згрупованих даних
  • Комбінування результатів запитів

Відмінність від flatten():

  • collapse() - один рівень
  • flatten() - рекурсивно всі рівні

Порада: використовуйте flatten() для глибоко вкладених структур.

// Масив масивів
$data = collect([
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
]);

$flat = $data->collapse();
// [1, 2, 3, 4, 5, 6, 7, 8, 9]

// Колекції у колекції
$tags = collect([
  collect(['php', 'laravel']),
  collect(['javascript', 'vue']),
  collect(['mysql', 'redis']),
]);

$allTags = $tags->collapse();
// ['php', 'laravel', 'javascript', 'vue', 'mysql', 'redis']

// Приклад: об'єднання дозволів користувача з ролей
$user->roles->map(fn($role) => $role->permissions)->collapse();

// Групування, а потім collapse
$orders = Order::all()
  ->groupBy('user_id')
  ->map(fn($userOrders) => $userOrders->pluck('items'))
  ->collapse();
// Відмінність collapse vs flatten
$nested = collect([
  [1, [2, [3, 4]]],
  [5, [6, [7, 8]]],
]);

$nested->collapse(); // [1, [2, [3, 4]], 5, [6, [7, 8]]]
$nested->flatten();  // [1, 2, 3, 4, 5, 6, 7, 8]

// Об'єднання масивів із кількох моделей
$allEmails = collect([$users, $admins, $moderators])
  ->map(fn($group) => $group->pluck('email'))
  ->collapse()
  ->unique();

// Теги з постів
$uniqueTags = Post::with('tags')->get()
  ->map(fn($p) => $p->tags)
  ->collapse()
  ->unique('id');

// Комбінування результатів пошуку
$results = collect([$localResults, $apiResults])
  ->collapse()
  ->sortByDesc('relevance');
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, стає новим значенням колекції.

$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));
});

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

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

Зараз опубліковано 22 матеріали від 2 авторів. Останній матеріал - 28 вересня 2026.