Lewati ke isi
JRG++JRG++ v0.2.0

JRG 9 · JRG Lanjut

Fungsi sebagai Nilai

Fungsi di JRG bukan cuma sesuatu yang dipanggil — ia bisa disimpan di variabel, dititipkan ke fungsi lain, dan dibuat di tempat.

fungsionalMenyimpan fungsi di variabel

fn-nilai.jrg
fn dua(n: int) -> int { return n * 2 }

pub fn main() {
    let f = dua           // disimpan, belum dipanggil
    wok(f(21))
    wok(typeof(f))
}
42
function

Closure: fungsi tanpa nama

Kalau fungsinya cuma dipakai sekali, tidak perlu diberi nama. Bentuk ringkasnya memakai sepasang garis tegak.

closure.jrg
pub fn main() {
    let kuadrat = |x| x * x
    let tambah = |a, b| a + b
    wok(kuadrat(7))
    wok(tambah(3, 4))
}
49
7
tangkap.jrg
pub fn main() {
    let pajak = 0.11
    let hitung = |harga| harga * (1.0 + pajak)
    wok(hitung(100000.0))
}
111000.00000000001

Tiga fungsi yang mengubah cara kamu menulis

FungsiGunanyaHasilnya
arr::mapUbah setiap elemenArray baru, panjang sama
arr::filterSaring yang memenuhi syaratArray baru, biasanya lebih pendek
arr::reducePeras jadi satu nilaiSatu nilai
map-filter.jrg
pub fn main() {
    let n = [12, 7, 25, 3, 18]

    wok("Dikuadratkan:", arr::map(n, |x| x * x))
    wok("Yang genap  :", arr::filter(n, |x| x % 2 == 0))
    wok("Dijumlahkan :", arr::reduce(n, |a, b| a + b, 0))
}
Dikuadratkan: [144, 49, 625, 9, 324]
Yang genap  : [12, 18]
Dijumlahkan : 65

Bandingkan dengan menulisnya memakai perulangan — keduanya benar, tapi yang atas menyebutkan apa yang diinginkan, bukan bagaimana caranya.

banding-loop.jrg
pub fn main() {
    let n = [12, 7, 25, 3, 18]

    var genap = []
    for _, x in n {
        if x % 2 == 0 { genap = arr::push(genap, x) }
    }
    wok("Cara perulangan:", genap)
    wok("Cara filter    :", arr::filter(n, |x| x % 2 == 0))
}
Cara perulangan: [12, 18]
Cara filter    : [12, 18]

Merangkai beberapa langkah

rangkai.jrg
pub fn main() {
    let nilai = [45, 88, 92, 67, 79, 95]

    let lulus = arr::filter(nilai, |n| n >= 75)
    let bonus = arr::map(lulus, |n| n + 5)
    let total = arr::reduce(bonus, |a, b| a + b, 0)

    wok("Lulus :", lulus)
    wok("Bonus :", bonus)
    wok("Total :", total)
    wok("Rata2 :", str::format("{:.2}", total as float / len(bonus) as float))
}
Lulus : [88, 92, 79, 95]
Bonus : [93, 97, 84, 100]
Total : 374
Rata2 : 93.50

Fungsi yang menerima fungsi

Kamu bisa menulis fungsimu sendiri yang menerima fungsi sebagai parameter.

terima-fn.jrg
fn terapkanDuaKali(f, x) {
    return f(f(x))
}

pub fn main() {
    wok(terapkanDuaKali(|n| n * 3, 2))
    wok(terapkanDuaKali(|s| s + "!", "hore"))
}
18
hore!!

Kuis 1

Apa hasil arr::map([1,2,3], |x| x * 10)?

Kuis 2

Fungsi mana yang memeras array jadi satu nilai?

Latihan mandiri

1. Dari [3, 8, 15, 4, 22], ambil yang lebih dari 5 lalu kalikan 2.

2. Cari hasil kali semua isi [1, 2, 3, 4] memakai reduce.

Jawaban 1: arr::map(arr::filter(a, |x| x > 5), |x| x * 2) → [16, 30, 44].
Jawaban 2: arr::reduce(a, |x, y| x * y, 1) → 24. Perhatikan nilai awalnya 1, bukan 0.