Kodealgo

Array Reduce JavaScript: Sintaks dan Contoh Penggunaan

reduce() merupakan method array di JavaScript yang mengeksekusi fungsi callback pada setiap elemen array, nilai hasil kalkulasi pada elemen sebelumnya digunakan untuk melakukan kalkulasi pada elemen berikutnya.

Setelah menjalankan fungsi callback untuk semua elemen array, method ini menghasilkan nilai tunggal.

Kasus yang paling mudah dipahami adalah ketika kita ingin menjumlahkan semua elemen array angka.

Method ini memang terlihat agak rumit pada awalnya, tapi jangan khawatir karena ini akan kita pelajari secara perlahan mulai dari sintaks hingga contoh penggunaannya.

  1. Sintaks
  2. Cara Kerja reduce
    1. Tanpa nilaiAwal
    2. Dengan nilaiAwal
  3. Contoh
    1. Menjumlahkan Nilai Objek Dalam Array
    2. Menyisipkan Objek ke Array
    3. Mengganti filter().map() dengan reduce()

Sintaks

// arrow function
reduce((nilaiSebelumnya, nilaiSaatIni, indexSaatIni, array) => { ... }, nilaiAwal)

// callback function
reduce(callbackFn, nilaiAwal)

Parameter

  • callbackFn: fungsi callback yang dieksekusi untuk setiap elemen array. Menerima empat argumen berikut:

    • nilaiSebelumnya: nilai yang dikembalikan dari fungsi callback sebelumnya.
    • nilaiSaatIni: nilai elemen array saat ini.
    • indeksSaatIni (opsional): indeks elemen saat ini.
    • array (opsional): array sumber.
  • nilaiAwal (opsional):

    Jika ditentukan, nilai ini akan digunakan oleh nilaiSebelumnya saat pertama kali callback dipanggil, dan nilaiSaatIni akan berisi nilai elemen pertama pada array.

    Jika tidak, nilaiSebelumnya akan menggunakan elemen pertama array dan nilaiSaatIni menggunakan elemen kedua.

Nilai Kembalian

Mengembalikan nilai yang dihasilkan oleh fungsi callback sampai akhir elemen array.

Method ini dapat mengembalikan kesalahan TypeError jika array tidak memiliki elemen dan nilaiAwal tidak disediakan.

Cara Kerja reduce()

Mari kita gunakan array sederhana untuk memahami cara kerja reduce().

Untuk mengurangi distraksi, saya tidak akan membahas indeksSaatIni dan array karena indeksSaatIni hanya diinisialisasi dengan indeks elemen saat ini yang sedang diiterasi/diulang.

Sedangkan array diinisialisasi dengan array sumber.

Keduanya bersifat opsional, boleh kita hilangkan.

Yang terpenting adalah memahami nilai dari argumen nilaiSebelumnya dan nilaiSaatIni.

Tanpa nilaiAwal

Mari kita gunkaan contoh sederhana, dalam kasus kali ini kita akan menjumlahkan semua elemen pada array arrAngka, tanpa nilaiAwal.

const arrAngka = [1, 2, 3, 4, 5];

const result = arrAngka.reduce((nilaiSebelumnya, nilaiSaatIni) => {
  return nilaiSebelumnya + nilaiSaatIni;
});

console.log(result); // 15

Dalam kasus ini fungsi callback dipanggil sebanyak empat kali, berikut langkah-langkahnya:

Pengulangan callbacknilaiSebelumnyanilaiSaatIniNilai Kembalian
Pertama123
Kedua336
Ketiga6410
Keempat10515

Perhatikan gambar berikut.

JavaScript Reduce Tanpa Nilai Awal

Yang perlu diperhatikan di sini, ketika callback dipanggil pertama kali, nilai dari nilaiSebelumnya akan menggunakan nilai dari elemen pertama array, 1.

Sedangkan nilaiSaatIni menggunakan nilai elemen kedua dari array, 2.

Oleh karena itu, pada iterasi pertama fungsi callback menghasilkan nilai 3 hasil dari penjumlahan nilaiSebelumnya + nilaiSaatIni (1 + 2).

Karena masih ada elemen array, maka nilai ini tidak langsung dikembalikan, melainkan diinisialisasi ke nilaiSebelumnya untuk pemanggilan callback berikutnya.

Jadi, pada pengulangan callback kedua, nilaiSebelumnya sekarang bernilai 3 sedangkan nilaiSaatIni bergeser menggunakan elemen array berikutnya yaitu 3.

Singkatnya, tanpa nilaiAwal:

Pada panggilan callback pertama, nilaiSebelumnya menggunakan nilai elemen pertam array, sedangkan nilaiSaatIni menggunakan elemen kedua.

Dengan nilaiAwal

Mari kita gunakan array yang sama, tapi sekarang kita inisialisasi nilaiAwal dengan 5.

const arrAngka = [1, 2, 3, 4, 5];

const result = arrAngka.reduce((nilaiSebelumnya, nilaiSaatIni) => {
  return nilaiSebelumnya + nilaiSaatIni;
}, 5);

console.log(result); // 20

Dalam kasus kali ini fungsi callback dipanggil sebanyak lima kali, berikut langkah-langkahnya:

Pengulangan callbacknilaiSebelumnyanilaiSaatIniNilai Kembalian
Pertama516
Kedua628
Ketiga8311
Keempat11415
Kelima15520

Perhatikan gambar berikut.

JavaScript Reduce Dengan Nilai Awal

Yang perlu diperhatikan di sini, nilai dari nilaiSebelumnya tidak lagi menggunakan elemen pertama array, melainkan nilai dari nilaiAwal yaitu 5.

Sedangkan nilaiSaatIni menggunakan elemen pertama array. Oleh karena itu menghasilkan nilai 20.

Selebihnya sama dengan contoh sebelumnya.

Jadi, dengan nilaiAwal:

Pada panggilan callback pertama, nilaiSebelumnya menggunakan nilai dari nilaiAwal, sedangkan nilaiSaatIni menggunakan elemen pertama array.

Contoh

Menjumlahkan Nilai Objek Dalam Array

Mari kita gunakan contoh yang agak kompleks.

Kita di sini ingin mengetahui berapa total nilai mahasiswa jika dijumlahkan.

const mahasiswa = [
  { nama: 'ucup', nilai: 80 },
  { nama: 'budi', nilai: 90 },
  { nama: 'bambang', nilai: 75 },
];

const totalNilai = mahasiswa.reduce((nilaiSebelumnya, nilaiSaatIni) => {
  return nilaiSebelumnya + nilaiSaatIni.nilai;
}, 0);

console.log(totalNilai); // 245

Kita disini perlu mengisi nilaiAwal dengan 0, kalau tidak, pada panggilan callback pertama, nilaiSebelumnya akan diinisialisasi dengan elemen pertama pada array yaitu objek { nama: 'ucup', nilai: 80 }.

Karena nilaiAwal ditentukan, nilaiSaatIni akan menggunakan elemen pertama pada array yaitu { nama: 'ucup', nilai: 80 }.

Oleh karena itu di dalam badan fungsi kita perlu menggunakan notasi titik untuk mengakses nilai dari properti nilai (nilaiSaatIni.nilai).

Menyisipkan Objek ke Array

Saat membuat aplikasi kadang kita perlu mengatur ulang struktur array, tujuannya tentu saja agar lebih terstruktur.

Misalnya, ini array yang kita miliki sekarang.

['reza', 'ucup', 'udin'];

Di sini kita ingin memasukkan setiap elemen array ke dalam objek berisi properti name untuk masing-masing elemen saat ini dan gender kita isi dengan male.

Jadi, ini yang kita inginkan.

[
  { name: 'reza', gender: 'male' },
  { name: 'ucup', gender: 'male' },
  { name: 'udin', gender: 'male' },
];

Masalah ini sebetulnya bisa diselesaikan dengan map, tapi inilah jika kita menggunakan reduce.

const usersMale = ['reza', 'ucup', 'udin'];

const refactUsersMale = usersMale.reduce((prev, user) => {
  return [
    ...prev,
    {
      name: user,
      gender: 'male',
    },
  ];
}, []);

console.log(refactUsersMale);
/* output:
[
  { name: 'reza', gender: 'male' },
  { name: 'ucup', gender: 'male' },
  { name: 'udin', gender: 'male' }
]
*/

Contoh kali ini ada yang berbeda dari sebelumnya, kali ini nilaiAwal disi dengan array kosong ([]).

Ya, kita bisa mengisi nilaiAwal dengan nilai apa pun termasuk angka, string, array, objek dan sebagainya.

...prev (titik tiga) adalah sintaks spread, jika Anda belum mempelajarinya, jangan khawatir, Anda bisa kembali ke sini kapan saja.

Mengganti filter().map() dengan reduce()

reduce bisa kita gunakan sebagai pengganti filter().map() yang lebih efisien.

Misalnya, kita memiliki array sebagai berikut.

[1, 2, 3, 4, 6];

Kita ingin memfilter bilangan genap ([2, 4, 6]) lalu kita kalikan semuanya dengan 2, sehingga hasilnya seperti ini.

[4, 8, 12];

Kita tidak bisa menangani kasus seperti ini hanya menggunakan map, karena callback map harus mengembalikan nilai, kalau tidak, nilai undefined dikembalikan.

Apalagi jika hanya menggunkan filter, tidak bisa.

Mereka berdua saling melengkapi.

Jadi, inilah jika kita menggunakan filter().map().

const numbers = [1, 2, 3, 4, 6];

const result = numbers.filter((num) => num % 2 === 0).map((num) => num * 2);

console.log(result); // [ 4, 8, 12 ]

Tidak ada yang salah dengan metode di atas. Tapi, ini kurang efisien.

Perulangan atau callback dieksekusi sebanyak 8 kali, bukan 10 kali, apalagi 5 kali hanya karena elemennya ada 5.

5 kali untuk filter, dan 3 kali untuk map.

Kenapa map hanya 3 kali? Karena filter mengembalikan array berisi 3 elemen.

Kita bisa mengatasi ini dengan reduce agar perulangan hanya dilakukan sebanyak 5 kali.

Jadi, inilah jika kita menggunakan reduce.

const numbers = [1, 2, 3, 4, 6];

const result = numbers.reduce((prev, curr) => {
  if (curr % 2 === 0) {
    prev.push(curr * 2);
  }

  return prev;
}, []);

console.log(result); // [ 4, 8, 12 ]