22. Tabel sebagai list — Solusi PR

File solusi .lua ada di exercises/22/homework/solutions/.

Soal 1 — Game favorit

Soal. Cetak daftar bernomor menggunakan ipairs.

Cara memikirkannya. ipairs memberikan indeks dan nilai sekaligus. Bangun setiap baris dari indeks, titik, spasi, dan nilainya.

Solusi.

local games = {"Roblox", "Minecraft", "Terraria", "Stardew Valley", "Hades"}

for i, name in ipairs(games) do
    print(i .. ". " .. name)
end

Keluaran:

1. Roblox
2. Minecraft
3. Terraria
4. Stardew Valley
5. Hades

Kesalahan umum.

  • Indeks dimulai dari 0: for i = 0, #games do print(games[i]) end. Putaran pertama mencetak nil karena posisi 0 tidak memiliki nilai.
  • Memakai pairs alih-alih ipairs. Keduanya memang bisa dipakai pada list, tapi pairs tidak menjamin urutan, jadi lebih baik pakai ipairs.

Soal 2 — Jumlahkan isi list

Soal. Tambahkan semua angka dalam sebuah list; cetak totalnya.

Cara memikirkannya. Simpan total yang terus diperbarui dengan total = total + value di dalam perulangan. Dengan ipairs kamu tidak perlu menggunakan indeksnya.

Solusi.

local scores = {12, 7, 24, 9, 30}

local total = 0
for _, value in ipairs(scores) do
    total = total + value
end

print("Total: " .. total)

_ adalah nama konvensional yang artinya aku tidak peduli dengan nilai ini. Ini variabel biasa yang tidak punya arti khusus bagi Lua, hanya petunjuk bagi yang membaca kode.

Kesalahan umum.

  • Lupa menulis total = 0 sebelum perulangan. nil + 12 adalah error.

Soal 3 — Insert dan remove

Soal. Lakukan empat operasi pada list, cetak list setelah setiap langkah.

Cara memikirkannya. Tulis satu rutinitas kecil untuk mencetak lalu panggil setelah setiap langkah (sebuah fungsi, seperti yang diperkenalkan di bab 21). Dengan begitu setiap operasinya hanya satu baris.

Solusi.

local list = {"apple", "banana", "cherry"}

local function show(label)
    io.write(label .. ": ")
    for i, v in ipairs(list) do
        io.write(v)
        if i < #list then io.write(", ") end
    end
    print()
end

show("Start          ")
table.insert(list, "date")
show("After append   ")
table.insert(list, 1, "apricot")
show("After insert@1 ")
table.remove(list)
show("After remove   ")
table.remove(list, 2)
show("After remove@2 ")

Contoh keluaran yang disingkat:

Start          : apple, banana, cherry
After append   : apple, banana, cherry, date
After insert@1 : apricot, apple, banana, cherry, date
After remove   : apricot, apple, banana, cherry
After remove@2 : apricot, banana, cherry

Kesalahan umum.

  • Menulis list[2] = nil alih-alih table.remove(list, 2). Cara itu meninggalkan lubang di posisi 2 dan merusak ipairs.

Tantangan — Balik list

Soal. reverse(list) mengembalikan list baru, list asli tidak berubah.

Cara memikirkannya. Bangun tabel baru di dalam fungsi. Telusuri list asli dari akhir ke awal (perulangan for yang menghitung mundur), tambahkan setiap nilai ke tabel baru, lalu kembalikan hasilnya.

Solusi.

local function reverse(list)
    local result = {}
    for i = #list, 1, -1 do
        table.insert(result, list[i])
    end
    return result
end

local fruits = {"apple", "banana", "cherry"}
print(table.concat(fruits, ", "))            -- apple, banana, cherry

local reversed = reverse(fruits)
print(table.concat(reversed, ", "))          -- cherry, banana, apple
print(table.concat(fruits, ", "))            -- apple, banana, cherry (unchanged)

table.concat(list, sep) menggabungkan list berisi string dengan pemisah. Tidak ada bab yang membahasnya sebelumnya, tapi ini alat yang paling pas untuk menampilkan isi list dalam satu baris.

Kesalahan umum.

  • Memodifikasi list langsung alih-alih membangun tabel baru. Soal menyatakan list asli harus tetap tidak berubah.
  • Melakukan perulangan dengan for i = 1, #list do dan menetapkan nilai ke result[i]. Cara itu membangun result dengan urutan yang sama seperti aslinya, bukan terbalik. Kuncinya ada di langkah -1.

Selesai?

Bab berikutnya mengajarkan cara lain menggunakan tabel — sebagai kamus dengan kunci yang punya nama. Kedua bentuk ini bisa ada dalam satu tabel.