Laravel Tutorial

Bài 21: Collection trong Laravel

Collection trong Laravel là một class được tích hợp sẵn các phương thức thường xuyên được sử dụng để xử lý dữ liệu nhằm giảm thiểu tối đa thời gian cho các lập trình viên. Đặc biệt là khi làm việc với API kết nối với database vì dữ liệu từ database trả về sẵn kiểu là Collection

1. Khai báo và cách sử dụng

Trước tiên, muốn sử dụng được collection bạn cần khai báo namespace của nó. Hãy thêm dòng này vào đầu file php của bạn

use Illuminate\Support\Collection;

Sau đó, bạn có thể tạo collection bằng 1 trong các cách sau đây:

use Illuminate\Support\Collection;

$collection = collect([1, 2, 3]);
//Hoặc
$collection = new Collection([1, 2, 3]);
//Hoặc
$collection = Collection::make([1, 2, 3]);

Lúc này, nếu bạn sử dụng hàm prinf_r($collection) thì PHP sẽ trả về cho chúng ta một object có chứa giá trị tương ứng mà ta đã truyền vào: Illuminate\Support\Collection Object ( [items:protected] => Array ( [0] => 1 [1] => 2 [2] => 3 ) )

2. Các phương thức hỗ trợ trong Collection

Trong collection Laravel hỗ trợ rất nhiều phương thức (khoảng gần 150 phương thức). Dưới đây chúng ta cùng tìm hiểu 1 số hàm thường được sử dụng, các bạn có thể xem đầy đủ tại đây.

all

Hàm này sẽ trả về rất cả các phần tử đang có trong collection

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

avg(), average()

Hàm này sẽ trả về giá trị trung bình của các phần tử có trong mảng theo key

$average = collect([1, 1, 2, 4])->avg();
// 2

Mảng lồng nhau

$average = collect([
    ['foo' => 10],
    ['foo' => 10],
    ['foo' => 20],
    ['foo' => 40]
])->avg('foo');
// 20

chunk()

Hàm này chia collection ra thành các collection nhỏ hơn theo size quy định

$collection = collect([1, 2, 3, 4, 5, 6, 7]);
$chunks = $collection->chunk(4);
$chunks->all();
// [[1, 2, 3, 4], [5, 6, 7]]

collapse()

Hàm này sẽ biến 1 collection của nhiều mảng thành collection của một mảng

$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]

collect()

Hàm này sẽ trả về một collection mới với các giá trị trong collection hiện tại

$collectionA = collect([1, 2, 3]);
$collectionB = $collectionA->collect();
$collectionB->all();
// [1, 2, 3]

concat()

Hàm này sẽ nối các giá trị vào cuối của mảng trong collection

$collection = collect(['John Doe']);
$concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']);
$concatenated->all();
// ['John Doe', 'Jane Doe', 'Johnny Doe']

contains()

Hàm này sẽ kiểm tra xem một value nào đó có tồn tại trong collection hay không

$collection = collect(['name' => 'Desk', 'price' => 100]);

$collection->contains('Desk');

// true

$collection->contains('New York');

// false

Với tham số truyền vào là nhiều giá trị

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Chair', 'price' => 100],
]);

$collection->contains('product', 'Bookcase');

// false

$collection->contains('price', 200);

// true

Với tham số truyền vào là một closure

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

$collection->contains(function ($value, $key) {
    return $value > 5;
});

// false

count()

Hàm này sẽ trả về số phần tử có trong collection

$collection = collect([1, 2, 3, 4]);
$collection->count();
// 4

dd()

Hàm này sẽ dump ra các giá trị đang có trong mảng

$collection = collect(['John Doe', 'Jane Doe']);
$collection->dd();
// array:2 [▼
    0 => "John Doe"
    1 => "Jane Doe"
   ]

diff()

Hàm này sẽ trả về các giá trị khác nhau giữa hai mảng data

$collection = collect([1, 2, 3, 4, 5]);
$diff = $collection->diff([2, 4, 6, 8]);
$diff->all();
// [1, 3, 5]

each()

Hàm này sẽ lặp các giá trị trong collection và thực thi code trong closure

$collection = collect([1, 2, 3, 4, 5]);
$collection = $collection->each(function ($value, $key) {
    if($value > 3){
        echo 'item > 3 ';
    } else {
        echo 'item < 3 ';
    }
});
// item < 3 item < 3 item < 3 item > 3 item > 3

filter()

Hàm này này sẽ lặp qua các phần từ trong collection và thực thi logic trong closure, nếu closure trả về false thì phần tử này sẽ không được trả về trong kết quả

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

$filtered = $collection->filter(function ($value, $key) {
    return $value > 2;
});

$filtered->all();

// [3, 4]

first()

Hàm này sẽ trả về giá trị đầu tiên pass với điều kiện trong closure

collect([1, 2, 3, 4])->first();
// 1

Có tham số truyền vào

collect([1, 2, 3, 4])->first(function ($value, $key) {
    return $value > 2;
});
// 3

flip()

Hàm này sẽ đảo ngược các giá trị key với value tương ứng trong mảng

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$flipped = $collection->flip();

$flipped->all();

// ['taylor' => 'name', 'laravel' => 'framework']

get()

Hàm này sẽ trả về các giá trị tương ướng với key truyền vào, nếu không tồn tại nó sẽ trả về null

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$value = $collection->get('name');

// taylor

sum()

Hàm này sẽ trả về tổng các giá trị của các phần tử trong collection

$collection = collect([1, 2, 3, 4]);
$collection = $collection->sum();
// 10

min()

Hàm này  sẽ trả về giá trị nhỏ nhất của các phần tử trong collection

$collection = collect([1, 2, 3, 4]);
$collection = $collection->min();
// 1

max()

Hàm này  sẽ trả về giá trị lớn nhất của các phần tử trong collection

$collection = collect([1, 2, 3, 4]);
$collection = $collection->max();
// 4

toArray()

Hàm này sẽ convert collection về dạng array

$collection = collect([1, 2, 3, 4]);
$collection = $collection->toAray();
// [[1, 2, 3, 4]]

toJson()

Hàm này sẽ convert collection về dạng JSON string

$collection = collect(['name' => 'Desk', 'price' => 200]);

$collection->toJson();

// '{"name":"Desk", "price":200}'

4. Kế thừa collection

Nếu bạn cần tạo thêm hàm, bạn có thể sử dụng macro với cú pháp sau:

Collection::macro($methodName, $closure);

Trong đó:

  • $methodName là tên của phương thức bạn muốn thêm.
  • $closure là một callback function chứa logic xử lý của phương thức

Ví dụ: Tạo hàm toUpper cho collection

use Illuminate\Support\Str;

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

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

Macro với tham số truyền vào

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Lang;

Collection::macro('toLocale', function ($locale) {
    return $this->map(function ($value) use ($locale) {
        return Lang::get($value, [], $locale);
    });
});

$collection = collect(['first', 'second']);

$translated = $collection->toLocale('es');

// ['first', 'second']

5. LazyCollection

Nếu bạn muốn sử dụng collection với dữ liệu lớn bạn có thể xem xét sử dụng LazyCollection. Class này được base trên PHP generator nên nó sử dụng rất ít tài nguyên

Để tạo LazyCollection các bạn sử dụng cú pháp:

LazyCollection::make();

Ví dụ:

use Illuminate\Support\LazyCollection;

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

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

 

Leave a Comment