Menu
CoddyTech

Generator dan Iterator

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan PHP di Coddy. Pelajaran 62 dari 91.

Generator menyediakan cara sederhana untuk membuat iterator tanpa mengimplementasikan seluruh interface Iterator. Fungsi generator menggunakan yield, bukan return, untuk menghasilkan nilai satu per satu dan menjeda eksekusi di antara setiap nilai.

Berikut generator dasar yang menghasilkan urutan angka:

<?php
function countTo(int $max): Generator {
    for ($i = 1; $i <= $max; $i++) {
        yield $i;
    }
}

foreach (countTo(3) as $number) {
    echo "$number\n";
}

Output:

1
2
3

Keunggulan utamanya adalah efisiensi memori. Alih-alih membangun seluruh array di memori, generator menghasilkan nilai sesuai kebutuhan. Ini sangat penting saat bekerja dengan kumpulan data berukuran besar, generator yang memproses satu juta catatan menggunakan memori yang sama dengan generator yang memproses sepuluh catatan.

Generator juga dapat menghasilkan pasangan kunci-nilai:

<?php
function userGenerator(): Generator {
    yield 'admin' => 'Alice';
    yield 'editor' => 'Bob';
}

foreach (userGenerator() as $role => $name) {
    echo "$role: $name\n";
}

Output:

admin: Alice
editor: Bob

Agar class buatanmu sendiri dapat diiterasi dengan foreach, implementasikan interface Iterator. Namun, dalam kebanyakan kasus, generator menawarkan solusi yang lebih rapi dengan lebih sedikit kode boilerplate. Generator sangat berguna dalam OOP ketika sebuah class perlu menyediakan kumpulan item tanpa memuat semuanya ke memori sekaligus.

challenge icon

Tantangan

Mudah

Mari kita buat sistem inventaris produk yang menggunakan generator untuk melakukan iterasi secara efisien melalui koleksi besar tanpa memuat semuanya ke memori sekaligus. Kamu akan membuat class yang menyimpan produk dan menyediakan method generator untuk melakukan iterasi dengan berbagai cara.

Kamu akan mengatur kodemu dalam tiga file:

  • Product.php: Buat class Product yang mewakili item dalam inventaris. Gunakan promosi konstruktor untuk menetapkan $sku publik bertipe string, $name publik bertipe string, dan $price publik bertipe float.
  • Inventory.php: Buat class Inventory yang mengelola koleksi produk dan menyediakan method generator untuk melakukan iterasi melaluinya. Sertakan file Product. Class ini harus:
    • Memiliki property array privat untuk menyimpan produk
    • Memiliki method addProduct(Product $product) yang menambahkan produk ke koleksi
    • Memiliki method generator allProducts(): Generator yang menghasilkan setiap produk satu per satu
    • Memiliki method generator expensiveProducts(float $minPrice): Generator yang hanya menghasilkan produk dengan harga lebih besar dari atau sama dengan nilai minimum yang diberikan, dengan menghasilkan pasangan key-value yang key-nya adalah SKU dan nilainya adalah produk
  • main.php: Sertakan file Inventory. Kamu akan menerima satu input: ambang harga minimum.

    Buat sebuah Inventory dan tambahkan tiga produk berikut:

    • SKU: "A001", Nama: "Laptop", Harga: 999.99
    • SKU: "A002", Nama: "Mouse", Harga: 29.99
    • SKU: "A003", Nama: "Monitor", Harga: 349.99

    Pertama, lakukan iterasi melalui allProducts() dan cetak nama setiap produk pada barisnya sendiri.

    Kemudian cetak satu baris kosong, lalu lakukan iterasi melalui expensiveProducts() menggunakan ambang input. Untuk setiap produk mahal, cetak "[sku]: [name] - $[price]" pada barisnya sendiri. Format harga dengan tepat 2 angka di belakang desimal.

Tantangan ini menunjukkan cara generator memungkinkan kamu melakukan iterasi secara malas melalui koleksi: setiap produk hanya dihasilkan saat diminta, sehingga pendekatan ini hemat memori untuk inventaris besar. Penghasilan key-value dalam expensiveProducts() menunjukkan cara generator dapat menyediakan data iterasi yang terstruktur.

Coba sendiri

<?php

require_once 'Inventory.php';

// Baca input
$minPrice = floatval(trim(fgets(STDIN)));

// TODO: Buat instance Inventory

// TODO: Tambahkan tiga produk:
// SKU: "A001", Nama: "Laptop", Harga: 999.99
// SKU: "A002", Nama: "Mouse", Harga: 29.99
// SKU: "A003", Nama: "Monitor", Harga: 349.99

// TODO: Iterasi melalui allProducts() dan cetak nama setiap produk

// TODO: Cetak baris kosong

// TODO: Iterasi melalui expensiveProducts() menggunakan $minPrice
// Untuk setiap produk mahal, cetak "[sku]: [name] - $[price]"
// Format harga dengan tepat 2 angka di belakang koma

?>
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler PHP online