Skip to content

Collections

Giới thiệu (Introduction)

Class Illuminate\Support\Collection cung cấp fluent wrapper thuận tiện để làm việc với mảng dữ liệu. Ví dụ:

php
$collection = collect(['Taylor', 'Abigail', null])
    ->map(function (?string $name) {
        return strtoupper($name);
    })
    ->reject(function (string $name) {
        return empty($name);
    });

Class Collection cho phép chain methods để fluent mapping và reducing mảng. Collections nói chung là immutable — mỗi method trả về instance Collection mới.

Tạo Collections (Creating Collections)

Dùng helper collect:

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

GHI CHÚ

Kết quả của Eloquent queries luôn trả về Collection instances.

Mở rộng Collections (Extending Collections)

Thêm methods tùy chỉnh bằng macro trong AppServiceProvider:

php
use Illuminate\Support\Collection;

Collection::macro('toUpper', function () {
    return $this->map(function (string $value) {
        return Str::upper($value);
    });
});

$collection = collect(['first', 'second'])
    ->toUpper();
// ['FIRST', 'SECOND']

Các Methods có sẵn (Available Methods)

Laravel Collections cung cấp hàng trăm methods. Dưới đây là những methods phổ biến nhất:

Thao tác cơ bản

php
// all() - Trả về array gốc
$collection->all();

// count() - Đếm số phần tử
$collection->count();

// first() - Phần tử đầu tiên
collect([1, 2, 3])->first(); // 1
collect([1, 2, 3])->first(fn ($v) => $v > 1); // 2

// last() - Phần tử cuối
collect([1, 2, 3])->last(); // 3

// isEmpty() / isNotEmpty()
collect([])->isEmpty();      // true
collect([1])->isNotEmpty();  // true

Lọc và Tìm kiếm

php
// filter() - Lọc theo điều kiện
collect([1, 2, 3, 4])->filter(fn ($v) => $v > 2);
// [3, 4]

// reject() - Loại bỏ theo điều kiện
collect([1, 2, 3, 4])->reject(fn ($v) => $v > 2);
// [1, 2]

// where() - Lọc theo key/value
collect($users)->where('active', true);

// contains() - Kiểm tra có chứa
collect([1, 2, 3])->contains(2); // true

// search() - Tìm index
collect([2, 4, 6])->search(4); // 1

// unique() - Loại trùng
collect([1, 1, 2, 2, 3])->unique(); // [1, 2, 3]

Biến đổi

php
// map() - Biến đổi từng phần tử
collect([1, 2, 3])->map(fn ($v) => $v * 2);
// [2, 4, 6]

// flatMap() - Map và flatten
collect([['name' => 'Sally'], ['name' => 'Taylor']])
    ->flatMap(fn ($values) => array_map('strtoupper', $values));

// pluck() - Trích xuất giá trị
collect($users)->pluck('email');
collect($users)->pluck('email', 'name'); // keyed by name

// transform() - Biến đổi in-place (mutate)
$collection->transform(fn ($v) => $v * 2);

// flatten() - Phẳng hóa mảng nhiều chiều
collect([1, [2, 3], [4, [5]]])->flatten();
// [1, 2, 3, 4, 5]

Sắp xếp

php
// sort() - Sắp xếp
collect([3, 1, 2])->sort()->values();
// [1, 2, 3]

// sortBy() - Sắp xếp theo key
collect($users)->sortBy('name');
collect($users)->sortByDesc('age');

// reverse() - Đảo ngược
collect([1, 2, 3])->reverse();
// [3, 2, 1]

Nhóm và Gộp

php
// groupBy() - Nhóm theo key
collect($users)->groupBy('department');

// chunk() - Chia nhóm
collect([1, 2, 3, 4, 5])->chunk(2);
// [[1, 2], [3, 4], [5]]

// merge() - Gộp
collect([1, 2])->merge([3, 4]);
// [1, 2, 3, 4]

// combine() - Kết hợp keys và values
collect(['name', 'age'])->combine(['Taylor', 28]);
// ['name' => 'Taylor', 'age' => 28]

// zip() - Ghép cặp
collect(['Chair', 'Desk'])->zip([100, 200]);
// [['Chair', 100], ['Desk', 200]]

Tính toán

php
// sum() - Tổng
collect([1, 2, 3])->sum(); // 6
collect($orders)->sum('price');

// avg() / average() - Trung bình
collect([1, 2, 3])->avg(); // 2

// min() / max()
collect([1, 2, 3])->min(); // 1
collect([1, 2, 3])->max(); // 3

// reduce() - Gộp thành một giá trị
collect([1, 2, 3])->reduce(fn ($carry, $item) => $carry + $item, 0);
// 6

// countBy() - Đếm theo giá trị
collect([1, 2, 2, 2, 3])->countBy();
// [1 => 1, 2 => 3, 3 => 1]

Truy cập

php
// get() - Lấy theo key
collect(['name' => 'Taylor'])->get('name'); // Taylor

// only() - Chỉ giữ keys
collect(['id' => 1, 'name' => 'Taylor', 'email' => 'a@b.com'])
    ->only(['name', 'email']);

// except() - Bỏ keys
collect(['id' => 1, 'name' => 'Taylor'])
    ->except(['id']);

// take() - Lấy n phần tử
collect([1, 2, 3, 4])->take(2);  // [1, 2]
collect([1, 2, 3, 4])->take(-2); // [3, 4]

// skip() - Bỏ qua n phần tử
collect([1, 2, 3, 4])->skip(2); // [3, 4]

// slice() - Cắt
collect([1, 2, 3, 4, 5])->slice(2); // [3, 4, 5]

Xuất kết quả

php
// toArray() - Chuyển thành array
$collection->toArray();

// toJson() - Chuyển thành JSON
$collection->toJson();

// each() - Duyệt (side effects)
collect($users)->each(function (User $user) {
    // ...
});

// dd() / dump() - Debug
$collection->dd();
$collection->dump();

Xem danh sách đầy đủ 100+ methods trên trang docs gốc.

Higher Order Messages

Collections hỗ trợ "higher order messages" — shortcut cho thao tác phổ biến:

php
$users->each->markAsVip();
$users->filter->isActive();
$users->sum->votes;

Lazy Collections

LazyCollection sử dụng PHP generators cho phép làm việc với dataset rất lớn mà giữ memory usage thấp:

php
use App\Models\User;

$users = User::cursor()
    ->filter(function (User $user) {
        return $user->isPremium();
    });

foreach ($users as $user) {
    echo $user->name;
}

Tạo Lazy Collections

php
use Illuminate\Support\LazyCollection;

LazyCollection::make(function () {
    $handle = fopen('log.txt', 'r');

    while (($line = fgets($handle)) !== false) {
        yield $line;
    }
});

The Enumerable Contract

Hầu hết methods của Collection đều có sẵn trong LazyCollection. Tuy nhiên mutating methods (như shift, pop, prepend) không có trong LazyCollection.