Menu
CoddyTech

Pola Iterator

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan Lua di Coddy. Pelajaran 64 dari 70.

Ketika kamu memiliki kumpulan item yang disimpan di dalam object, kamu sering ingin melakukan perulangan melalui item-item tersebut. for generik Lua bekerja dengan fungsi iterator apa pun: fungsi ini memanggil fungsi tersebut sebelum setiap iterasi dan berhenti ketika fungsi mengembalikan nil.

Pola Iterator memberi objek sebuah method yang mengembalikan fungsi seperti itu. Fungsi tersebut menyimpan posisinya dalam variabel lokal, jadi posisi itu milik satu perulangan, bukan milik koleksi:

local Collection = {}
Collection.__index = Collection

function Collection:new()
    local obj = { items = {} }
    setmetatable(obj, Collection)
    return obj
end

function Collection:add(item)
    table.insert(self.items, item)
end

function Collection:iter()
    local index = 0
    return function()
        index = index + 1
        return self.items[index]
    end
end

Setiap pemanggilan bag:iter() membuat fungsi baru dengan index-nya sendiri, dimulai dari 0. Fungsi ini adalah closure: fungsi ini tetap dapat menggunakan index dan self setelah iter selesai dijalankan. Setelah item terakhir, self.items[index] bernilai nil, dan perulangan berhenti:

local bag = Collection:new()
bag:add("apple")
bag:add("banana")

for item in bag:iter() do
    print(item)  -- apple, lalu banana
end

for item in bag:iter() do
    print(item)  -- apple, lalu banana lagi
end

Jangan simpan posisi di dalam koleksi itu sendiri. Jika object menyimpan self.index dan bertindak sebagai iteratornya sendiri, perulangan pertama akan meninggalkan indeks di akhir, sehingga perulangan kedua tidak akan mencetak apa pun, dan perulangan yang berhenti lebih awal dengan break akan membuat perulangan berikutnya dimulai dari tengah.

challenge icon

Tantangan

Mudah

Mari buat class Playlist yang bisa kamu telusuri dengan for loop generik Lua! Kamu akan menerapkan pola Iterator dengan method :iter() yang mengembalikan fungsi iterator.

Kamu akan menyusun kodemu dalam dua file:

  • Playlist.lua: Buat class Playlist yang menyimpan lagu secara internal. Class-mu memerlukan konstruktor :new() yang menginisialisasi list lagu kosong dan method :addSong(title) yang menambahkan lagu ke dalamnya. Yang terpenting, tambahkan method :iter() yang mengembalikan fungsi baru setiap kali dipanggil. Fungsi itu menyimpan posisinya dalam variabel lokal dan mengembalikan lagu berikutnya setiap kali dipanggil, atau nil jika tidak ada lagu lagi.
  • main.lua: Muat module Playlist-mu dan buat playlist baru. Tambahkan lagu berdasarkan input yang kamu terima, lalu gunakan for loop generik pada playlist:iter() untuk mencetak setiap judul lagu pada barisnya sendiri.

Karena setiap pemanggilan :iter() dimulai dari lagu pertama, playlist yang sama bisa ditelusuri berulang kali.

Kamu akan menerima tiga input, yang masing-masing mewakili judul lagu untuk ditambahkan ke playlist-mu secara berurutan.

Misalnya, jika inputnya adalah Bohemian Rhapsody, Stairway to Heaven, dan Hotel California, outputnya seharusnya:

Bohemian Rhapsody
Stairway to Heaven
Hotel California

Jika inputnya adalah Yesterday, Imagine, dan Let It Be, outputnya seharusnya:

Yesterday
Imagine
Let It Be

Coba sendiri

-- Muat module Playlist dengan require
local Playlist = require('Playlist')

-- Baca tiga judul lagu dari input
local song1 = io.read()
local song2 = io.read()
local song3 = io.read()

-- TODO: Buat playlist baru menggunakan Playlist:new()

-- TODO: Tambahkan ketiga lagu ke playlist menggunakan :addSong()

-- TODO: Gunakan for loop generik untuk menelusuri playlist:iter()
-- dan cetak setiap judul lagu pada baris tersendiri
-- Petunjuk: for song in playlist:iter() do ... end
quiz iconUji dirimu

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

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler Lua online