Budi menata stok toko serba adanya dalam satu daftar produk; setiap produk membawa nama, harga, dan kategori. Dari daftar tunggal itu muncul tiga kebutuhan yang berulang setiap hari. Untuk etalase, Budi perlu daftar nama saja — bentuk data diubah. Untuk promosi, hanya produk elektronik yang ditampilkan — data disaring. Untuk laporan, total nilai seluruh stok harus dihitung — data dirangkum menjadi satu angka.
JavaScript menyediakan satu method untuk setiap kebutuhan itu: map, filter, dan reduce. Ketiganya menerima function callback — materi section Functions — dan menjadi pola pengolahan data yang paling sering dipakai di JavaScript modern.
Persiapan: Satu Dataset Produk #
Kita menulis setiap produk sebagai object literal dengan tiga properti. Pada tahap ini cukup pahami cara menulis dan membacanya — produk[0].nama dibaca “properti nama milik elemen pertama” — karena pembahasan menyeluruh tentang object menunggu di section Objects:
const produk = [
{ nama: "Kabel USB", harga: 25000, kategori: "elektronik" },
{ nama: "Buku Catatan", harga: 15000, kategori: "atk" },
{ nama: "Charger", harga: 45000, kategori: "elektronik" },
{ nama: "Mouse", harga: 60000, kategori: "elektronik" },
{ nama: "Pulpen", harga: 8000, kategori: "atk" },
];
console.log(produk.length);
console.log(produk[0].nama);Output yang Dihasilkan:
5
Kabel USBDataset lima produk inilah yang akan kita olah bertahap sampai akhir chapter.
map: Mengubah Setiap Elemen #
Aturan map: jalankan callback untuk setiap elemen, kumpulkan kembalian callback, dan kembalikan semuanya sebagai array baru. Panjang array hasil selalu sama dengan asalnya, tetapi bentuk nilainya bebas kita tentukan — string jadi number, object jadi nama, angka jadi kuadratnya:
const angka = [1, 2, 3];
const kuadrat = angka.map((n) => n * n);
console.log(kuadrat);
console.log(angka);Output yang Dihasilkan:
[ 1, 4, 9 ]
[ 1, 2, 3 ]Baris pertama menunjukkan setiap elemen dipetakan menjadi kuadratnya; baris kedua menegaskan array asal tidak tersentuh. Callback (n) => n * n dipanggil tiga kali — sekali per elemen, berurutan dari depan — dan hasil ketiga pemanggilan itu dikumpulkan oleh map.
filter: Menyaring yang Lolos Kriteria #
Aturan filter: callback bertugas sebagai uji (predicate) yang mengembalikan nilai benar atau salah. Hanya elemen yang lolos uji yang masuk ke array hasil — kriteria berlaku selektif, sehingga panjang hasil boleh berbeda dari asalnya:
const pengeluaran = [12, 7, 8, 3];
const genap = pengeluaran.filter((n) => n % 2 === 0);
console.log(genap);
console.log(pengeluaran);Output yang Dihasilkan:
[ 12, 8 ]
[ 12, 7, 8, 3 ]Callback n % 2 === 0 mengembalikan true untuk 12 dan 8, dan false untuk sisanya, sehingga hanya dua angka itu yang lolos. Array asal tetap empat elemen. Bila tidak ada elemen yang lolos, filter mengembalikan array kosong [] — bukan error, dan bukan undefined.
Kriteria boleh menggabungkan lebih dari satu syarat dengan operator logika dari section Operators — misalnya item.kategori === "atk" && item.harga < 10000 menyaring barang ATK yang terjangkau sekaligus. Callback tetap mengembalikan satu nilai benar-salah; penggabungan hanya terjadi di dalam ekspresinya, dan filter tidak pernah mengetahui bedanya.
reduce: Merangkum Menjadi Satu Nilai #
Aturan reduce: seluruh array dirangkum menjadi satu nilai. Callback menerima dua parameter — akumulator (hasil sementara) dan elemen saat ini — dan kembaliannya menjadi akumulator untuk putaran berikutnya. Argumen kedua reduce adalah nilai awal akumulator.
const belanjaan = [5000, 3000, 2000];
const total = belanjaan.reduce((total, item) => total + item, 0);
console.log(total);Output yang Dihasilkan:
10000Untuk melihat mekanismenya, kita telusuri putaran demi putaran:
| Putaran | total saat masuk | item | total saat keluar |
|---|---|---|---|
| 1 | 0 | 5000 | 5000 |
| 2 | 5000 | 3000 | 8000 |
| 3 | 8000 | 2000 | 10000 |
Akumulator memulai dari 0 (nilai awal), lalu menampung kembalian callback di tiap putaran. Setelah elemen terakhir, akumulasi itulah hasil akhir reduce: satu angka 10000. Dengan pola yang sama, reduce bisa merangkum menjadi string terpanjang, array unik, atau object rekap — satu nilai apa pun yang kita rancang.
Penamaan parameter membantu banyak orang saat membaca ulang kode: beri nama akumulator sesuai isinya — total untuk penjumlahan, terpanjang untuk pencarian string — dan beri nama elemen tunggal item atau sesuai isinya. Nama yang tepat menggantikan setengah penjelasan.
Merangkai: filter, lalu map, lalu reduce #
Ketiga method saling melengkapi karena keluaran masing-masing berupa array — kecuali reduce yang mengakhiri rantai dengan satu nilai. Pola filter → map → reduce membaca seperti kalimat: saring dulu, ubah bentuknya, rangkum hasilnya. Berkas berikut menerapkan ketiganya bertahap pada dataset produk:
// map-filter-reduce.js
// Satu dataset produk dipakai bertahap: map, filter, reduce, lalu dirangkai.
const produk = [
{ nama: "Kabel USB", harga: 25000, kategori: "elektronik" },
{ nama: "Buku Catatan", harga: 15000, kategori: "atk" },
{ nama: "Charger", harga: 45000, kategori: "elektronik" },
{ nama: "Mouse", harga: 60000, kategori: "elektronik" },
{ nama: "Pulpen", harga: 8000, kategori: "atk" },
];
// --- 1. map: mengubah setiap elemen menjadi nilai baru ---
const daftarNama = produk.map((item) => item.nama);
console.log(daftarNama);
// --- 2. filter: menyaring elemen yang lolos kriteria ---
const elektronik = produk.filter((item) => item.kategori === "elektronik");
for (const item of elektronik) {
console.log(`${item.nama} - Rp${item.harga}`);
}
// --- 3. reduce: merangkum seluruh array menjadi satu nilai ---
const totalNilaiStok = produk.reduce((total, item) => total + item.harga, 0);
console.log(totalNilaiStok);
// --- 4. Merangkai ketiganya: filter -> map -> reduce ---
const totalElektronikDiskon = produk
.filter((item) => item.kategori === "elektronik")
.map((item) => item.harga - 5000) // potongan Rp5.000 per item
.reduce((total, harga) => total + harga, 0);
console.log(totalElektronikDiskon);Output yang Dihasilkan:
[ 'Kabel USB', 'Buku Catatan', 'Charger', 'Mouse', 'Pulpen' ]
Kabel USB - Rp25000
Charger - Rp45000
Mouse - Rp60000
153000
115000Mari kita telaah baris-baris pentingnya:
- Baris 13 (
produk.map((item) => item.nama)): callback mengambil propertinamadari tiap produk, sehinggamapmenghasilkan array lima nama — bentuk berubah, panjang tetap lima. - Baris 17 (
produk.filter((item) => item.kategori === "elektronik")): hanya tiga produk elektronik yang lolos uji; loopfor...ofdi baris 18–20 mencetaknya satu per satu. - Baris 23 (
produk.reduce((total, item) => total + item.harga, 0)): akumulator menjumlahkan propertihargasemua produk — lima putaran menghasilkan153000, nilai stok keseluruhan. - Baris 28 (
.filter((item) => item.kategori === "elektronik")): rantai dimulai; hasil tahap ini array tiga produk elektronik. - Baris 29 (
.map((item) => item.harga - 5000)): tahap kedua menerima hasil tahap pertama dan mengubah tiap harga menjadi harga setelah potongan Rp5.000 —25000,40000,55000. - Baris 30 (
.reduce((total, harga) => total + harga, 0)): tahap akhir menjumlahkan tiga harga terkoreksi menjadi115000— total nilai elektronik setelah potongan.
Rantai tiga tahap itu padat, tetapi setiap tahapnya sederhana dan berurutan dari atas ke bawah. Bila perlu memeriksa isi antara, kita bisa memecah rantai menjadi tiga konstanta seperti contoh sebelumnya — hasilnya identik.
Callback yang diteruskan ke map sebenarnya menerima lebih dari elemen: argumen kedua berisi index elemen itu, dan index inilah yang membuat penomoran otomatis mungkin tanpa variabel penghitung terpisah:
const daftarNama = ["Siti", "Budi", "Rina"];
const nomorAntrean = daftarNama.map((nama, i) => `${i + 1}. ${nama}`);
for (const baris of nomorAntrean) {
console.log(baris);
}Output yang Dihasilkan:
1. Siti
2. Budi
3. RinaPolanya sering dipakai untuk tampilan etalase dan daftar pilihan. Yang perlu diingat: map tetap menghasilkan array, dan loop for...of dari chapter Mengakses Elemen yang menangani pencetakan satu per satu.
Merantai atau Memecah #
Rantai filter().map().reduce() terlihat padat, dan kepadatan itu bisa menjadi kekuatan atau beban. Kebiasaan yang sehat: pertahankan rantai untuk alur yang sudah akrab dan pendek, dan pecah menjadi konstanta bernama ketika logikanya mulai dipikirkan ulang. Untuk memeriksa keadaan antara saat debugging, cukup pisahkan satu tahap — const elektronik = produk.filter(...) disertai console.log(elektronik.length) — lalu lanjutkan tahap berikutnya dari konstanta itu.
Kedua gaya menghasilkan keluaran yang identik; yang berubah hanyalah seberapa banyak keadaan antara yang terlihat. Karena setiap tahap mengembalikan array baru, memecah rantai tidak menambah mutasi apa pun — data asal tetap aman di kedua gaya.
map, filter, dan reduce memproses seluruh daftar sampai habis. Ketika yang dibutuhkan hanya satu elemen tertentu — “produk pertama di bawah sepuluh ribu” — atau pemeriksaan benar-salah atas seluruh isi, method pencarian dan pemeriksaan di chapter berikutnya lebih tepat dipakai.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
map-filter-reduce.js
Unduh berkas// map-filter-reduce.js
// Satu dataset produk dipakai bertahap: map, filter, reduce, lalu dirangkai.
const produk = [
{ nama: "Kabel USB", harga: 25000, kategori: "elektronik" },
{ nama: "Buku Catatan", harga: 15000, kategori: "atk" },
{ nama: "Charger", harga: 45000, kategori: "elektronik" },
{ nama: "Mouse", harga: 60000, kategori: "elektronik" },
{ nama: "Pulpen", harga: 8000, kategori: "atk" },
];
// --- 1. map: mengubah setiap elemen menjadi nilai baru ---
const daftarNama = produk.map((item) => item.nama);
console.log(daftarNama);
// --- 2. filter: menyaring elemen yang lolos kriteria ---
const elektronik = produk.filter((item) => item.kategori === "elektronik");
for (const item of elektronik) {
console.log(`${item.nama} - Rp${item.harga}`);
}
// --- 3. reduce: merangkum seluruh array menjadi satu nilai ---
const totalNilaiStok = produk.reduce((total, item) => total + item.harga, 0);
console.log(totalNilaiStok);
// --- 4. Merangkai ketiganya: filter -> map -> reduce ---
const totalElektronikDiskon = produk
.filter((item) => item.kategori === "elektronik")
.map((item) => item.harga - 5000) // potongan Rp5.000 per item
.reduce((total, harga) => total + harga, 0);
console.log(totalElektronikDiskon);