Navigation

Laravel

Laravel How to Group a Collection with `groupBy()`

Organize Laravel collections into groups using groupBy(). Perfect for categorizing data by common attributes or creating nested structures.

Problem: You have a collection of items and need to organize them into groups based on a specific attribute, like grouping users by role or products by category.

Solution:

// Basic groupBy
$users = collect([
    ['name' => 'John', 'role' => 'admin', 'city' => 'NYC'],
    ['name' => 'Jane', 'role' => 'user', 'city' => 'LA'],
    ['name' => 'Bob', 'role' => 'admin', 'city' => 'NYC'],
    ['name' => 'Alice', 'role' => 'user', 'city' => 'NYC']
]);

$byRole = $users->groupBy('role');
// Result:
// [
//     'admin' => [['name' => 'John'...], ['name' => 'Bob'...]],
//     'user' => [['name' => 'Jane'...], ['name' => 'Alice'...]]
// ]

// Group by nested attribute
$byCity = $users->groupBy('address.city');

// Group by multiple levels
$grouped = $users->groupBy(['role', 'city']);
// Result: nested groups - first by role, then by city

// Custom grouping logic
$byNameLength = $users->groupBy(function ($user) {
    return strlen($user['name']);
});

// From database query
$orders = Order::with('customer')
    ->get()
    ->groupBy('status');

$ordersByMonth = Order::get()->groupBy(function ($order) {
    return $order->created_at->format('Y-m');
});

// Preserve keys after grouping
$products = Product::all()
    ->groupBy('category_id')
    ->map(function ($group) {
        return $group->sum('price');
    });

// Group and count
$userCounts = User::all()
    ->groupBy('role')
    ->map->count();

Why it works: groupBy() creates a new collection where items are organized by the specified key. The original items remain unchanged, just reorganized. When using a callback, you can create custom grouping logic based on any criteria.

Performance tip: For large datasets from the database, consider using SQL GROUP BY with aggregates instead of collection grouping.

Table Of Contents

Related Topics

Share this article

Add Comment

No comments yet. Be the first to comment!

More from Laravel