Laravel Collections Macros Higher Order Helpers Pipeline
Selesai membaca dokumentasi ini?
Kembali ke rujukan utama Laravel untuk melanjutkan topik lainnya.
Kembali ke rujukan utama Laravel untuk melanjutkan topik lainnya.
Illuminate\Support\Collection adalah pembungkus array di Laravel yang membawa puluhan method chaining untuk transformasi data. collect($array) membuat instance baru. Sebagian besar method mengembalikan Collection baru, bukan mengubah yang lama.
LazyCollection adalah varian yang menunda evaluasi dan memproses item satu per satu lewat generator — cocok untuk dataset besar yang tidak boleh dimuat ke memory sekaligus.
Collection::macro() memperluas Collection dengan method custom tanpa subclass, lewat trait Macroable yang sudah disematkan di kelas Collection.
map → filter → reduce).foreach + array PHP mentah dengan operasi deklaratif yang mudah diraitakan.LazyCollection).->toUpper()) ke semua Collection di project via macro().Collection biasa (eager) mengevaluasi seluruh item saat method dipanggil dan menyimpan hasil di memory. LazyCollection mengevaluasi item saat dibutuhkan (lazy), sehingga map/filter tidak memicu iterasi penuh sampai ada konsumsi seperti each(), toArray(), first(), atau take() yang menyentuh item.
use Illuminate\Support\Collection;
use Illuminate\Support\LazyCollection;
// Eager: semua item langsung diproses & disimpan di memory
$hasil = collect([1, 2, 3, 4])
->map(fn ($x) => $x * 2)
->filter(fn ($x) => $x > 4)
->values();
// Lazy: diproses satu per satu saat dikonsumsi
$stream = LazyCollection
map memanggil callback untuk tiap item dan mengembalikan Collection baru berisi hasil callback. Collection asli tidak berubah.
$angka = collect([1, 2, 3]);
$double = $angka->map(fn ($x) => $x * 2); // [2, 4, 6]
// $angka tetap [1, 2, 3]filter menyimpan item di mana callback bernilai truthy. reject adalah kebalikannya. Keduanya mengembalikan Collection baru.
$aktif = $users->filter(fn ($u) => $u->active);
$nonaktif = $users->reject(fn ($u) => $u->active);reduce menjumlahkan/menggabungkan item jadi nilai tunggal (skalar atau tipe apa pun yang dikembalikan callback), bukan Collection.
$total = collect([1, 2, 3])->reduce(
fn ($carry, $item) => $carry + $item,
0
); // 6, bukan Collectionpipe(callable) — teruskan Collection ke callable dan kembalikan nilai apapun yang dikembalikan callable (terminal, seperti reduce tapi bebas bentuk).tap(callable) — jalankan side-effect (logging, assert) lalu kembalikan Collection aslinya tanpa diubah.$out = collect([1, 2, 3])
->pipe(fn ($c) => $c->sum() * 2); // 12
collect([1, 2, 3])
->tap(Laravel punya higher-order proxy: map, filter, reject, each, groupBy, sortBy, dsb. bisa dipanggil tanpa closure bila yang diinginkan adalah memanggil method/property tiap item.
// setara dengan $users->map(fn ($u) => $u->name)
$nama = $users->map->name;
// saring item yang property/method aktif bernilai truthy
$aktif = $users->filter->active;
// panggil method tiap item (side-effect)
$users->each->notify();Daftarkan macro di boot() service provider (biasanya AppServiceProvider). Di dalam closure, $this merujuk ke instance Collection yang sedang dipanggil.
use Illuminate\Support\Collection;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
Collection::macro('toUpper'
collect(['a', 'b'])->toUpper(); // ['A', 'B']Macro tersedia di semua Collection di aplikasi setelah didaftarkan. Jangan mendeklarasikan Collection::macro() di dalam controller/closure yang bisa berjalan berulang — deklarasi ganda memicu exception "macro already exists".
Catatan alur: map/filter/reject selalu mengembalikan Collection baru (immutable), sedangkan reduce/sum/max mengembalikan skalar. Jangan panggil method Collection lagi di atas hasil reduce.
Chaining tidak mengubah aslinya. map/filter/reject/slice mengembalikan instance baru. Lupa menampung hasilnya = perubahan hilang.
$c = collect([1, 2, 3]);
$c->map(fn ($x) => $x * 2); // hasil dibuang
// $c tetap [1, 2, 3]
$c = $c->map(fn ($x) => $x collect() eager memproses jutaan baris (pakai LazyCollection + cursor() dari Eloquent untuk hindari memory spike).map dan transform tanpa sadar sehingga muncul side-effect tak terduga.Collection::macro() di dalam closure yang dieksekusi berulang (bootstrap duplikat → exception).values() setelah filter lalu mengandalkan index berurut di JSON/loop berbasis angka.Object di dalam tetap referensi yang sama. map mengembalikan Collection baru, tapi bila item berupa object, ia masih menunjuk object asli. Mutasi object di dalam callback tetap mengubah object asli.
$users->map(function ($u) {
$u->name = strtoupper($u->name); // mengubah object asli!
return $u;
});transform itu mutating. transform() memodifikasi Collection di tempat (in-place), berbeda dengan map yang mengembalikan salinan.
$c = collect([1, 2, 3]);
$c->transform(fn ($x) => $x * 2); // $c sekarang [2, 4, 6]forget/push/put/splice memodifikasi instance. Method ini mutating, bukan mengembalikan salinan.
$c = collect(['a' => 1, 'b' => 2]);
$c->forget('b'); // $c langsung berubah jadi ['a' => 1]Key numerik di-reset oleh values(). filter/map mempertahankan key, jadi hasil bisa punya gap index.
collect([1, 2, 3, 4])
->filter(fn ($x) => $x > 2); // [2 => 3, 3 => 4]
// pakai ->values() kalau butuh index rapat 0, 1, ...reduce hasilnya bukan Collection. Memanggil ->map() di atas hasil reduce akan error karena skalar tidak punya method itu.