Jika kamu mempelajari bahasa pemrograman JavaScript, kamu akan menemukan istilah higher-order function. Meskipun awalnya akan terdengar rumit, namun sebenarnya mudah jika dipelajari dan dipahami. Yang membuat JavaScript cocok untuk bahasa pemrograman fungsional adalah karena JavaScript memiliki higher-order function. Sebenarnya Higher-Order function adalah fungsi yang common di JavaScript, jika kamu sudah pernah memprogram dengan bahasa JavaScript mungkin kamu pernah menggunakan tanpa menyadarinya.

Mengenal Higher-Order Function

Higher-Order function adalah fungsi yang beroperasi didalam fungsi lain, baik menggunakannya sebagai argumen atau mengembalikan nilainya. Secara sederhana, higher-order function adalah fungsi yang menerima fungsi sebagai argumen atau mengembalikan nilai fungsi sebagai output.

Dalam tulisan ini, kita akan membahas beberapa higher-order function, antara lain yaitu: map(), filter() dan reduce().

Array.map()

Array.map() adalah salah satu metode dari higher-order function bawaan yang berfungsi membuat array baru dengan memanggil fungsi callback yang disediakan sebagai argumen pada setiap elemen dalam array. Metode map() akan mengambil setiap nilai yang dikembalikan dari fungsi callback, lalu membuat array baru dengan menggunakan nilai-nilai yang baru.

Ilustrasi Array.map()

Untuk lebih jelasnya mari kita praktekkan saja, katakanlah kita memiliki array yang berisi number dengan nilai tahun lahir. Kita ingin membuat array baru yang menghitung umur dari tahun lahir tersebut dengan tahun sekarang.

Menggunakan for-loop tradisional

const tahunLahir = [1998, 1999, 2000, 2001, 2002]
const umur = []

for (let i = 0; i < tahunLahir.length; i++) {
  umur.push(new Date().getFullYear() - tahunLahir[i])
}

alert(umur) // hasil: [21,20,19,18,17]

Menggunakan Array.map()

const tahunLahir = [1998, 1999, 2000, 2001, 2002]
const umur = tahunLahir.map(tahun => new Date().getFullYear() - tahun)

alert(umur) // hasil: [21,20,19,18,17]

Bisa dilihat kode akan lebih singkat jika kita menggunakan Array.map(). Fungsi callback tahun => new Date().getFullYear() - tahun dipanggil pada setiap anggota array yang ada di variabel tahunLahir

Array.filter()

Array.filter() adalah salah satu metode dari higher-order function bawaan yang berfungsi untuk membuat array baru dengan mengoperasikan fungsi callback pada setiap anggota dengan mem-filter nilai-nilai didalam array yang sudah ada. Adapun argumen yang ada pada callback filter() adalah: value, index.

Ilustrasi Array.filter()

Untuk lebih jelasnya, mari kita coba actionnya. Katakanlah kita memiliki array yang berisi object dengan properti nama dan umur. Kita ingin membuat array yang hanya berisi orang-orang dengan usia yang lebih dari atau sama dengan 18 tahun.

Menggunakan for-loop tradisional dengan statement if

const orang = [
  { nama: 'Sutan', umur: 16 },
  { nama: 'Joni', umur: 18 },
  { nama: 'Mark', umur: 27 },
  { nama: 'Back', umur: 14 },
  { nama: 'Toni', umur: 24},
]

const orangDiizinkan = []

for (let i = 0; i < orang.length; i++) {
  if (orang[i].umur >= 18) {
    orangDiizinkan.push(orang[i].nama);
  }
}

alert(orangDiizinkan) // ['Joni','Mark','Toni']

Menggunakan Array.filter() dan Array.map()

let orang = [
  { nama: 'Sutan', umur: 16 },
  { nama: 'Joni', umur: 18 },
  { nama: 'Mark', umur: 27 },
  { nama: 'Back', umur: 14 },
  { nama: 'Toni', umur: 24},
]

orang = orang.filter(orang => orang.umur >= 18)
alert(orang.map(orang => orang.nama)) // ['Joni','Mark','Toni']

Array.reduce()

Array.reduce() adalah salah satu metode dari higher-order function bawaan yang berfungsi untuk menjalankan fungsi callback pada setiap anggota dari array yang dipanggil dengan menghasilkan single output. Metode reduce() menerima 2 parameter, yaitu fungsi callback dan initialValue (opsional but recommended). Sedangkan fungsi callback-nya menghasilkan 4 argumen, yaitu: accumulator, currentValue, currentIndex (opsional), sourceArray (opsional).

Jika tidak ada initialValue yang disediakan, maka accumulator akan sama dengan elemen pertama dalam array dan currentValue akan sama dengan elemen kedua dalam array.

Ilustrasi Array.reduce()

Memang agak rumit jika mendengar penjelasan reduce() ini. Untuk contoh sederhananya, anggaplah kita mempunyai data seperti ini:

const keranjang = [
  {
    produk: 'Indomie Mie Goreng',
    harga: 2500
  },
  {
    produk: 'Aqua Gelas',
    harga: 500
  },
  {
    produk: 'Sepatu Sport',
    harga: 75000
  }
]

Lalu, kita ingin menjumlahkan total harga dari properti harga yang ada pada data keranjang tersebut.

Dengan Menggunakan for-loop tradisional

let totalHarga = 0
for (let i = 0; i < keranjang.length; i++) {
  totalHarga += keranjang[i].harga
}
alert('Rp.' + totalHarga) // Hasil: Rp.78000

Menggunakan Array.reduce()

const totalHarga = keranjang.reduce((acc, cur) => acc + cur.harga, 0)
alert('Rp.' + totalHarga) // Hasil: Rp.78000

Terus, apa keunggulannya ?

Mungkin kamu akan bertanya - tanya apa keunggulan menggunakan higher-order function daripada for-loop tradisional seperti biasanya. Ya, dengan menggunakan higher-order function, kita dapat melakukan chaining. Chaining sendiri adalah sebuah teknik pemrograman yang menggunakan return dari satu fungsi sebagai argumen untuk fungsi seterusnya. Belum jelas ? mari kita lihat contohnya. Anggaplah kita mempunyai data seperti ini.

const siswa = [
  {
    nama: 'Sutan Gading',
    nilaiTugas: 70,
    nilaiUts: 80,
    nilaiUas: 74
  },
  {
    nama: 'Alex',
    nilaiTugas: 30,
    nilaiUts: 40,
    nilaiUas: 97
  },
  {
    nama: 'Si Muning',
    nilaiTugas: 25,
    nilaiUts: 40,
    nilaiUas: 75
  },
  {
    nama: 'Toni Stark',
    nilaiTugas: 60,
    nilaiUts: 70,
    nilaiUas: 94
  },
  {
    nama: 'Jay Boy',
    nilaiTugas: 40,
    nilaiUts: 50,
    nilaiUas: 54
  }
]

Dari data tersebut, kita ingin memperoleh rata-rata nilai akhir dari semua siswa yang lulus (Note: siswa yang lulus jika memperoleh nilai akhir lebih atau sama dengan dari 60). Dengan menggunakan metode chaining pada higher-order function. Kurang lebih penyelesainnya seperti ini:

const siswaLulus = siswa.map(item => ({
  nama: item.nama,
  nilaiAkhir: (item.nilaiTugas * 0.2) + (item.nilaiUts * 0.3) + (item.nilaiUas * 0.5)
})).filter(item => item.nilaiAkhir >= 60)

const rataNilaiLulus = siswaLulus.reduce((acc, cur) => acc + cur.nilaiAkhir, 0) / siswaLulus.length

document.writeln('Siswa yang lulus: ', JSON.stringify(siswaLulus, null, 2))
document.write('Rata-rata nilai siswa yang lulus: ', Number(rataNilaiLulus).toFixed(2))

...

...

Bagaimana ? simple dan singkat kan ? Mungkin akan lebih panjang dan bertele-tele jika kita menyelesaikan masalah di atas dengan menggunakan for-loop tradisional seperti biasanya. Jadi, higher-order function disini hadir untuk memudahkan dan mempersingkat penyelesaian masalah yang ada.

Kesimpulan

Sampai disini kita telah mengenal apa itu higher-order function. Singkatnya, higher-order function adalah fungsi yang dapat menerima parameter fungsi sebagai argumen dan bahkan dapat mengembalikan nilai dari fungsi. Higher-Order function sama seperti fungsi biasa dengan kemampuan tambahan untuk menerima dan mengembalikan fungsi lainnya dengan argumen dan output yang ditentukan. Sebenarnya masih ada lagi Higher-Order function bawaan yang ada pada bahasa pemrograman JavaScript, seperti: find(), sort() dan lainnya. Dan bahkan kita dapat membuat higher-order function sendiri loh! Hmm, mungkin lain kali kita akan bahas lagi. Jangan lupa share ya 😄

Bagikan