Pustaka table dan pustaka math melengkapi pengelolaan data serta perhitungan di dalam program Lua. Topik ini membahas table.insert, table.remove, table.sort, table.concat, dan table.unpack, lalu beralih ke fungsi pustaka math seperti floor, ceil, max, min, sqrt, dan random. Contoh yang digunakan berputar pada daftar piket kelas dan statistik nilai ujian, sehingga efek setiap fungsi terlihat pada data yang mudah dihitung ulang. Bagian akhir menghubungkan operator pembagian / dan // dengan fungsi math.type serta menjelaskan cara menghasilkan angka acak yang dapat direproduksi.
Menyisipkan dan menghapus elemen#
Fungsi table.insert(t, v) menambahkan nilai v pada akhir table yang berperan sebagai array, sedangkan bentuk table.insert(t, pos, v) menyisipkan nilai pada posisi tertentu dan menggeser elemen setelahnya. Fungsi table.remove(t, pos) bekerja sebaliknya, yaitu menghapus elemen pada posisi yang diberikan dan menggeser sisanya ke depan. Apabila posisi tidak diberikan, elemen terakhir yang dihapus, dan nilai elemen yang hilang dikembalikan oleh fungsi ini. Skrip berikut membangun daftar piket dari dua nama, menyisipkan dua nama tambahan, lalu menghapus dua nama pada langkah yang berbeda.
-- Mengelola daftar piket kelas dengan table.insert dan table.remove
local piket = { "Ali", "Budi" }
table.insert(piket, "Citra")
table.insert(piket, 1, "Dewi")
print(table.concat(piket, ", "))
table.remove(piket, 2)
print(table.concat(piket, ", "))
local keluar = table.remove(piket)
print("Elemen yang dihapus: " .. keluar)
print(table.concat(piket, ", "))Dewi, Ali, Budi, Citra
Dewi, Budi, Citra
Elemen yang dihapus: Citra
Dewi, BudiSisipan pada posisi 1 membuat “Dewi” berada di depan, sehingga urutan awal berubah menjadi Dewi, Ali, Budi, Citra. Penghapusan pada posisi 2 mengeluarkan “Ali” dan menutup celahnya dengan menggeser “Budi” serta “Citra”. Pemanggilan remove tanpa posisi menghapus elemen terakhir sekaligus mengembalikannya, sehingga nama “Citra” dapat ditampilkan sebelum table terakhir dicetak.
Mengurutkan dengan table.sort#
Fungsi table.sort(t) mengurutkan elemen array secara menaik dengan operator < bawaan. Pengurutan terjadi langsung pada table yang diberikan, bukan pada salinannya, sehingga table aslinya berubah dan fungsi tidak mengembalikan table baru. Apabila urutan lain diinginkan, sediakan fungsi pembanding (comparator) sebagai argumen kedua, misalnya function(a, b) return a > b end untuk urutan menurun.
-- Mengurutkan nilai ujian menaik dan menurun
local nilai = { 78, 91, 85, 69, 88 }
table.sort(nilai)
print(table.concat(nilai, ", "))
table.sort(nilai, function(a, b)
return a > b
end)
print(table.concat(nilai, ", "))69, 78, 85, 88, 91
91, 88, 85, 78, 69Hasil pertama mengikuti urutan menaik bawaan, sedangkan hasil kedua terbalik karena pembandingnya membalik arah perbandingan. Fungsi pembanding yang sama dapat digunakan untuk mengurutkan string, misalnya menyusun nama peserta menurut abjad, karena operator < dan > juga terdefinisi untuk string.
Menggabungkan dan membongkar table#
Fungsi table.concat(t, pemisah) menyambung seluruh elemen array menjadi satu string dengan pemisah opsional. Cara ini lebih efisien daripada menyambung string di dalam perulangan, karena Lua hanya menyusun satu string akhir dan tidak membuat string antara pada setiap langkah. Fungsi table.unpack(t) bergerak ke arah sebaliknya, yaitu melepaskan elemen table menjadi nilai balik ganda, sehingga cocok mengisi parameter fungsi yang jumlahnya berubah-ubah.
local huruf = { "a", "b", "c" }
print(table.concat(huruf, "-"))
local x, y, z = table.unpack({ 10, 20, 30 })
print(x, y, z)a-b-c
10 20 30Pemanggilan concat menghasilkan “a-b-c”, sedangkan unpack melepaskan tiga angka menjadi tiga variabel sekaligus. Pola local x, y, z = table.unpack(t) hanya tepat apabila jumlah elemen sudah diketahui, karena kelebihan nilai balik akan terbuang dan kekurangannya bernilai nil.
Fungsi math yang esensial#
Pustaka math menyediakan fungsi numerik yang paling sering dibutuhkan. Fungsi floor dan ceil membulatkan ke bawah dan ke atas, abs menghilangkan tanda negatif, max dan min memilih nilai terbesar dan terkecil, sedangkan sqrt menghitung akar kuadrat dan selalu menghasilkan bilangan pecahan (float). Dua konstantanya juga sering digunakan, yaitu math.pi dan math.huge. Konstanta math.huge menyatakan bilangan tak hingga dan berguna sebagai batas awal pencarian nilai terkecil. Skrip berikut menggabungkan beberapa fungsinya untuk statistik nilai ujian.
-- Statistik nilai ujian dengan fungsi pustaka math
local nilai = { 78, 91, 85, 69, 88 }
local total = 0
for _, v in ipairs(nilai) do
total = total + v
end
print(string.format("Nilai tertinggi: %d", math.max(table.unpack(nilai))))
print(string.format("Nilai terendah : %d", math.min(table.unpack(nilai))))
print(string.format("Rata-rata : %.2f", total / #nilai))Nilai tertinggi: 91
Nilai terendah : 69
Rata-rata : 82.20Argumen table.unpack(nilai) melepaskan seluruh nilai ujian menjadi argumen max dan min, sehingga nilainya tidak perlu ditulis satu per satu. Rata-rata dihitung dari pembagian nyata dan diformat dengan %.2f menjadi 82.20. Blok kode berikut menguji fungsi lain satu per satu.
print(math.floor(3.7), math.ceil(3.2))
print(math.abs(-12), math.sqrt(144))
print(math.pi)
print(math.max(4, 9, 2), math.min(4, 9, 2))
print(math.huge > 10 ^ 308)3 4
12 12.0
3.1415926535898
9 2
truePerhatikan bahwa sqrt(144) menghasilkan 12.0 dan bukan 12, karena pustaka math menjaga hasilnya tetap bertipe pecahan. Nilai math.pi tercetak sebagai 3.1415926535898, yaitu bentuk pembulatan format bawaan, sedangkan pemformatan eksplisit dengan %.2f memberikan 3.14. Pembandingan math.huge > 10 ^ 308 bernilai true karena tak hingga lebih besar dari bilangan pecahan berapa pun.
Pembagian, math.type, dan angka acak#
Lua 5.4 membedakan bilangan bulat (integer) dan bilangan pecahan secara tegas. Operator / selalu menghasilkan pecahan, sedangkan operator // melakukan pembagian bulat, yaitu pembagian yang dibulatkan ke bawah menuju negatif tak hingga. Fungsi math.type melaporkan tipe suatu bilangan sebagai integer atau float, sehingga perbedaan kedua operator dapat diperiksa secara langsung.
print(math.type(7 / 2), 7 / 2)
print(math.type(7 // 2), 7 // 2)
print(math.type(7.0 // 2), 7.0 // 2)
print(math.type(3), math.type(3.0))float 3.5
integer 3
float 3.0
integer floatBaris pertama menunjukkan 7 / 2 menghasilkan 3.5 bertipe float, baris kedua menunjukkan 7 // 2 menghasilkan 3 bertipe integer, dan baris ketiga menunjukkan bahwa pembagian bulat atas float tetap menghasilkan float. Baris terakhir menegaskan bahwa 3 dan 3.0 berbeda tipe meskipun nilainya sama, dan keduanya tetap dianggap sama oleh operator ==.
Angka acak dihasilkan oleh math.random(a, b), yang mengembalikan bilangan bulat di antara a dan b termasuk batasnya. Tanpa persiapan, deretnya berbeda pada setiap eksekusi karena Lua menggunakan sumber keacakan yang berubah-ubah. Fungsi math.randomseed(x) menetapkan titik awal deret, sehingga dengan nilai yang sama, deret yang dihasilkan juga sama pada setiap eksekusi. Sifat ini diperlukan untuk data uji dan simulasi yang harus dapat direproduksi.
math.randomseed(42)
print(math.random(1, 100))
print(math.random(1, 100))
print(math.random(1, 100))50
76
86Dengan math.randomseed(42) di awal, tiga pemanggilan berikutnya selalu menghasilkan 50, 76, dan 86 pada penerjemah yang sama. Menghilangkan baris seed akan menghasilkan deret yang berbeda pada setiap eksekusi.
Kesalahan umum#
Penggunaan kedua pustaka ini biasanya tersandung tiga hal berikut.
- Menghapus elemen dalam perulangan maju tanpa penyesuaian indeks.
table.removemenggeser elemen berikutnya ke depan, sehingga elemen pada posisi yang sama bisa terlewat. Perulangan mundur dari akhir, yaitufor i = #t, 1, -1, menghindari masalah ini. - Mengira
table.sortmengembalikan table baru. Fungsi ini mengembalikannildan mengubah table aslinya, sehingga hasil pengurutan harus dibaca dari table yang sama. - Memanggil
math.randomuntuk kebutuhan yang harus dapat direproduksi tanpamath.randomseed. Deretnya berubah pada setiap eksekusi, sehingga pengujian yang bergantung padanya tidak stabil. Tetapkan seed tetap sebelum deret pertama dihasilkan.
Ringkasan#
table.insertmenambah di akhir atau di posisi tertentu, sedangkantable.removemenghapus elemen, mengembalikan nilai yang dihapus, dan menggeser elemen lain.table.sortmengurutkan table asli secara menaik dan menerima fungsi pembanding untuk arah lain, sedangkantable.concatmenyambung elemen menjadi string dantable.unpackmelepaskannya menjadi nilai balik.floor,ceil,abs,max,min, dansqrtmencakup kebutuhan numerik dasar, ditambah konstantamath.pidanmath.huge.- Operator
/selalu menghasilkan float dan//melakukan pembagian bulat, sedangkanmath.randomyang didahuluimath.randomseedtetap menghasilkan deret yang dapat direproduksi.
Referensi#
- Lua 5.4 Reference Manual — Lua.org — Bagian 6.6 dan 6.7 mendokumentasikan fungsi manipulasi table serta fungsi matematika.
- Programming in Lua — Lua.org — Bab 19 dan 18 membahas pustaka table serta pustaka matematis beserta contoh penggunaannya.