23. Tabel sebagai kamus — Solusi PR

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

Soal 1 — Data pemain

Soal. Buat tabel pemain; cetak setiap field menggunakan pairs.

Cara berpikir. Buat literal dengan empat kunci, lalu pakai perulangan for k, v in pairs(...), satu print per pasangan.

Solusi.

local player = {
    name = "Keiko",
    class = "Mage",
    level = 7,
    alive = true,
}

for key, value in pairs(player) do
    print(key, value)
end

Urutan cetaknya tergantung pada cara Lua menyimpan data secara internal, jadi tidak selalu sama dengan urutan yang kamu tulis.

Kesalahan umum.

  • Menulis kunci dengan tanda kutip di dalam literal: {"name" = "Keiko"}. Di dalam {}, kunci bernama ditulis tanpa tanda kutip. Bentuk kurung siku {["name"] = "Keiko"} juga bisa, tapi yang tanpa kurung siku lebih lazim.

Soal 2 — Berat inventaris

Soal. Jumlahkan semua nilai dalam sebuah kamus.

Cara berpikir. Gunakan pairs, karena kuncinya berupa string. Simpan total yang terus bertambah seperti di bab 22.

Solusi.

local inventory = {
    sword = 3.5,
    shield = 5.0,
    potion = 0.2,
    map = 0.1,
    coins = 0.05,
}

local total = 0
for _, weight in pairs(inventory) do
    total = total + weight
end

print(string.format("Total weight: %.2f", total))

_ mengabaikan kunci; penjumlahan hanya butuh nilainya.

Kesalahan umum.

  • Menggunakan ipairs. Fungsi itu hanya melewati kunci numerik 1, 2, 3, ..., jadi untuk kamus, tidak ada yang dilewati sama sekali.

Soal 3 — Pencarian aman

Soal. lookup(dict, key) mengembalikan nilai atau "(not found)".

Cara berpikir. Cari dict[key]. Kembalikan nilainya kalau bukan nil; kalau nil, kembalikan string pengganti.

Solusi.

local function lookup(dict, key)
    local value = dict[key]
    if value == nil then
        return "(not found)"
    end
    return value
end

local player = { name = "Keiko", level = 7 }

print(lookup(player, "name"))     -- Keiko
print(lookup(player, "email"))    -- (not found)

local key = "level"
print(lookup(player, key))         -- 7

Fungsi ini bekerja untuk kunci apapun — string ("name"), variabel (key), bahkan angka kalau kamus tersebut memiliki kunci numerik.

Kesalahan umum.

  • Menggunakan if dict[key] then ... else ... end dan lupa bahwa false dianggap falsy. Kamus yang menyimpan someKey = false akan salah dilaporkan sebagai "not found". Pengecekan value == nil menghindari masalah itu.

Tantangan — Frekuensi kata

Soal. Hitung kemunculan setiap kata dalam sebuah daftar.

Cara berpikir. Lewati daftar satu kali. Untuk setiap kata, cari di counts; kalau belum ada, anggap hitungannya 0, lalu tambahkan 1 dan simpan kembali.

Idiom Lua untuk nol atau nilai saat ini adalah (counts[word] or 0). or mengembalikan sisi kiri kalau bernilai truthy, kalau tidak maka sisi kanan — jadi counts[word] yang nil menghasilkan 0.

Solusi.

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

local counts = {}
for _, word in ipairs(words) do
    counts[word] = (counts[word] or 0) + 1
end

for word, count in pairs(counts) do
    print(word, count)
end

Keluaran (urutan bisa berbeda):

apple    3
banana   2
cherry   1

Kesalahan umum.

  • Menulis counts[word] = counts[word] + 1 tanpa or 0. Saat pertama kali kata tersebut ditemui, counts[word] bernilai nil, dan nil + 1 akan menyebabkan error.

Selesai?

Selanjutnya, The table library memberikan alat siap pakai untuk mengurutkan dan menggabungkan daftar, dan bab terakhir Bagian 5 memecah kode ke beberapa file menggunakan modul. Setelah itu, mini-proyek Bagian 5 — Text Adventure — menggabungkan tabel, fungsi, dan modul menjadi sebuah game kecil.