Metode map dan filter mengolah array dengan mengoper satu fungsi kecil ke setiap elemennya, tanpa perulangan yang ditulis manual. Setelah topik ini, transformasi sebuah array menjadi array baru berukuran sama dan pemilihan butir yang lolos suatu syarat mengikuti pola yang baku. Topik ini juga menyandingkan kedua metode dengan perulangan manual yang setara, lalu menegaskan sifat terpentingnya, yaitu hasil kerja keduanya selalu array baru dan array asalnya tidak tersentuh.
map, satu masukan satu keluaran#
Metode map memanggil sebuah fungsi untuk setiap elemen array lalu mengumpulkan nilai baliknya menjadi array baru, dengan panjang yang persis sama seperti array asalnya. Fungsi yang dioper seperti ini disebut callback, yakni fungsi yang diberikan sebagai argumen agar dapat dipanggil kembali oleh kode lain. Karena satu elemen masuk dan satu keluaran keluar pada posisi yang sama, map dipakai untuk mengubah bentuk data, bukan untuk membuang atau menambah butir.
Contoh berikut mengonversi suhu Celcius ke Fahrenheit. Callback (c) => (c * 9) / 5 + 32 dijalankan empat kali, satu kali untuk setiap elemen, dan hasilnya ditampung di array baru bernama fahrenheit.
const celcius = [26, 30, 24, 28];
const fahrenheit = celcius.map((c) => (c * 9) / 5 + 32);
console.log(celcius);
console.log(fahrenheit);[ 26, 30, 24, 28 ]
[ 78.8, 86, 75.2, 82.4 ]Angkanya mudah diperiksa ulang, misalnya 26 dikali 9 dibagi 5 ditambah 32 menghasilkan 78.8. Urutan keluaran mengikuti urutan masukan karena map menelusuri array dari indeks 0 sampai terakhir. Array kosong juga menghasilkan array kosong, karena tidak ada elemen yang perlu dikonversi.
filter, memilih yang lolos uji#
Metode filter mengembalikan array baru. Isinya hanya elemen yang lolos syarat, yaitu elemen yang membuat callback menghasilkan nilai benar. Callback pada filter bertugas sebagai uji lulus atau gagal, bukan sebagai pengubah bentuk, sehingga isi elemennya tidak pernah dimodifikasi. Panjang array hasilnya paling banyak sama dengan array asal dan bisa jauh lebih pendek bila banyak butir tidak lolos.
const nilai = [78, 92, 65, 84, 71, 90];
const lulus = nilai.filter((n) => n >= 75);
console.log(lulus);
console.log(`array awal: ${nilai.length} butir, array lulus: ${lulus.length} butir`);[ 78, 92, 84, 90 ]
array awal: 6 butir, array lulus: 4 butirDari enam nilai ujian, empat yang mencapai batas minimal 75 dan semuanya terbawa dengan urutan yang tetap terjaga. Nilai 65 dan 71 tidak dihapus dari array nilai, melainkan hanya tidak ikut masuk ke array lulus. Bila tidak ada satu pun yang lolos, hasilnya array kosong, dan itu adalah jawaban yang sah untuk pertanyaan seleksi tersebut.
Tiga parameter pada callback#
Callback map dan filter dapat menerima hingga tiga parameter, yaitu nilai elemen, indeks elemen, dan array sumbernya. Parameter kedua dan ketiga ditulis hanya bila dibutuhkan, sehingga bentuk satu parameter seperti (c) => ... adalah bentuk yang paling umum. Parameter indeks berguna saat posisi ikut menjadi data, misalnya untuk memberi nomor urut pada setiap baris.
const nilai = [78, 92, 65, 84];
const berlabel = nilai.map((n, i) => `${i + 1}. ${n}`);
console.log(berlabel.join("\n"));1. 78
2. 92
3. 65
4. 84Ekspresi i + 1 menggeser indeks yang mulai dari 0 menjadi nomor urut yang mulai dari 1. Bentuk itu lebih wajar bagi pembaca daftar. Parameter ketiga, yaitu array sumber, dipakai lebih jarang, misalnya untuk membandingkan elemen dengan tetangganya di dalam callback. Sebagian besar callback memang hanya memakai parameter pertama, dan itu wajar karena parameter yang tidak ditulis tidak pernah diisi.
Berdampingan dengan perulangan manual#
Cara paling jelas memahami map dan filter adalah melihat tugas yang sama dikerjakan dua kali, satu dengan perulangan manual dan satu dengan kedua metode tersebut. Berkas berikut mencari siswa yang lulus, mengambil namanya, lalu menuliskannya huruf besar dengan kedua gaya. Keluaran kedua versinya diletakkan berdampingan agar kesetaraannya terlihat.
// Tujuan yang sama, dua cara: nama siswa yang lulus, ditulis huruf besar
const ujian = [
{ nama: "Ali", nilai: 78 },
{ nama: "Budi", nilai: 92 },
{ nama: "Citra", nilai: 65 },
{ nama: "Dewi", nilai: 84 },
];
// cara perulangan manual
const manual = [];
for (const siswa of ujian) {
if (siswa.nilai >= 75) {
manual.push(siswa.nama.toUpperCase());
}
}
// cara filter lalu map
const metode = ujian
.filter((s) => s.nilai >= 75)
.map((s) => s.nama.toUpperCase());
console.log(`manual : ${manual.join(", ")}`);
console.log(`metode : ${metode.join(", ")}`);manual : ALI, BUDI, DEWI
metode : ALI, BUDI, DEWI# jalankan berkas contoh dari direktori topik
node berdampingan.jsmanual : ALI, BUDI, DEWI
metode : ALI, BUDI, DEWIKeluaran blok bash sama persis karena perintahnya menjalankan berkas yang sama. Kedua versi menghasilkan ALI, BUDI, DEWI, tetapi pembacaannya berbeda. Pada versi manual, maksud program tersimpan di antara tanda kurung, variabel penampung, dan push, sehingga harus ditelusuri baris demi baris. Pada versi filter dan map, maksudnya terbaca dari nama metodenya, seleksi dulu, lalu ubah bentuk. Perulangan manual tetap tepat untuk tugas yang tidak sepadan satu lawan satu, misalnya tugas yang mengumpulkan hasil menjadi satu nilai.
Array hasil selalu baru#
map dan filter tidak pernah mengubah array asalnya, keduanya selalu membuat dan mengembalikan array baru. Sifat ini penting karena array lama tetap utuh untuk keperluan lain, misalnya dicetak ulang atau difilter lagi dengan syarat berbeda. Konsekuensinya, nilai baliknya harus ditampung atau diteruskan, karena hasil yang tidak ditampung akan terbuang begitu saja.
const awal = [26, 30, 24];
const dipanaskan = awal.map((c) => c + 2);
const panas = awal.filter((c) => c > 25);
console.log(awal);
console.log(dipanaskan);
console.log(panas);[ 26, 30, 24 ]
[ 28, 32, 26 ]
[ 26, 30 ]Array awal tetap berisi [26, 30, 24] setelah dua operasi, sementara dipanaskan dan panas adalah dua array baru yang masing-masing memegang hasil transformasi dan seleksinya. Satu kehalusan perlu dicatat: untuk array yang berisi object, yang berpindah ke array baru adalah referensinya, bukan salinan objectnya, sehingga mengubah properti object di array hasil ikut mengubah object di array asal. Bagaimanapun, panjang dan urutan array barunya tetap terpisah dari array sumber.
Kesalahan umum#
- Lupa
returnpada callback berkurung kurawal. Arrow function dengan badan{}tidak otomatis mengembalikan nilai, sehinggamapmenghasilkan array penuhundefineddanfilterkehilangan syarat ujinya. Pakai bentuk satu ekspresi tanpa kurung kurawal untuk callback pendek, atau tulisreturnsecara eksplisit di dalam badannya. Kesalahan ini sering tidak memunculkan error, karena keluarannya hanya tampak kosong atau tidak lengkap. - Mengira array asal ikut berubah. Hasil
mapataufilteryang tidak ditampung hilang begitu pernyataannya selesai, sedangkan variabel lama tetap berisi data awal. Simpan nilai baliknya ke variabel baru, misalnyaconst lulus = nilai.filter((n) => n >= 75), dan jangan menimpa nama array lama agar pembaca tidak berasumsi isinya berubah. - Memakai
maphanya untuk mencetak. Bila callback mengembalikan nilai yang tidak pernah dipakai, array hasilnya langsung terbuang dan maksud kodenya menyesatkan bagi pembaca berikutnya. Untuk tugas efek samping semacam ini, perulangan biasa menyatakan maksud dengan lebih jelas, sedangkan transformasi yang hasilnya dipakai tetap ditulis denganmap.
Ringkasan#
mapmenjalankan callback pada setiap elemen dan mengembalikan array baru dengan panjang yang sama seperti array asal.filtermengembalikan array baru berisi elemen yang lolos syarat callback, dengan urutan tetap terjaga.- Callback keduanya dapat menerima nilai, indeks, dan array sumber, dipakai secukupnya sesuai kebutuhan.
- Array hasil selalu baru dan array asal tidak berubah, sehingga nilai baliknya wajib ditampung agar tidak terbuang.
Referensi#
- Array.prototype.map() — MDN — dokumentasi map beserta urutan tiga parameter callback dan contoh pemakaiannya.
- Array.prototype.filter() — MDN — dokumentasi filter, termasuk perilaku seleksi dan array baru yang dihasilkannya.
- Array methods — javascript.info — bab map dan filter dengan banyak contoh kecil yang mudah dicoba ulang.