Array Methods Javascript Map Filter Reduce

| | | Javascript
Array Methods Javascript Map Filter Reduce

Array Methods JavaScript: Map, Filter, Reduce, Panduan Lengkap

array itu struktur data dasar di javascript. buat ngolah data di dalamnya, ES6 ngenalin tiga method yang paling sering dipakai: map, filter, dan reduce. sebelum lanjut, pastikan paham dulu perbedaan var, let, dan const, karena array methods ini biasanya ditulis pakai arrow function dengan deklarasi const.

ketiganya punya prinsip yang sama: alih-alih ngubah array asli, mereka ngembaliin array baru. hasilnya kode lebih pendek dan lebih gampang ditebak, karena array sumber nggak pernah ikut berubah diam-diam.

dulu saya nulis semua manipulasi data pakai for loop, dan sering kecelakaan sendiri, biasanya gara-gara index yang kelewat satu atau variabel penampung yang lupa direset 🙂 setelah menguasai map, filter, dan reduce, kebanyakan kode begitu menyusut jadi satu dua baris yang jauh lebih jelas. bagian chaining di akhir artikel adalah pola yang paling sering saya pakai di project nyata.

semua contoh di artikel ini bisa kalian jalankan langsung di console browser, tinggal copas aja biar kebayang sendiri hasilnya.

1. Array map buat transformasi data

map() dipakai buat bikin array baru dengan mentransformasi setiap elemen array asli lewat sebuah fungsi. sebenernya di balik map() ini ada for loop yang jalan otomatis, jadi kalian nggak perlu nulis loop manual lagi.

Sintaks

const arrayBaru = arrayAsli.map((item, index, array) => {
    return itemBaru;
});

callback di dalam map() nerima tiga parameter, tapi praktiknya cuma dua yang pertama yang paling sering kepake:

  • item, elemen yang lagi diproses, ini yang paling sering kepake
  • index, posisi elemen ke berapa, mulai dari 0. berguna kalau transformasinya butuh tahu posisi
  • array, array aslinya, jarang dipakai, tapi ada kalau-kalau dibutuhkan

hasil callback untuk tiap elemen dikumpulkan jadi array baru dengan urutan yang sama persis. map() nggak pernah ngubah array aslinya, dia selalu bikin array baru.

Contoh dasar

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

const dikaliDua = angka.map(item => item * 2);
console.log(dikaliDua); // [2, 4, 6, 8, 10]
console.log(angka);     // [1, 2, 3, 4, 5], array asli tidak berubah

lihat, angka tetap utuh setelah di-map. kalau transformasinya cuma satu baris ekspresi kayak item * 2, arrow function bisa dipendekin tanpa kurung dan tanpa return. begitu butuh lebih dari satu baris, baru pakai kurung kurawal dan return eksplisit.

index bisa dipakai buat transformasi yang butuh posisi, misalnya nambahin nomor urut:

const nama = ["Andi", "Budi", "Cici"];
const denganNomor = nama.map((item, index) => `${index + 1}. ${item}`);
console.log(denganNomor); // ["1. Andi", "2. Budi", "3. Cici"]

Kalau datanya array of objects

data di dunia nyata jarang berbentuk angka polos, biasanya array of objects. map() paling sering kepake buat ngeambil atau nambahin properti:

const users = [
    { nama: "Andi", umur: 25 },
    { nama: "Budi", umur: 30 },
    { nama: "Cici", umur: 22 }
];

// Ambil hanya nama
const daftarNama = users.map(user => user.nama);
console.log(daftarNama); // ["Andi", "Budi", "Cici"]

// Tambah properti baru
const withStatus = users.map(user => ({
    ...user,
    status: user.umur >= 17 ? "Dewasa" : "Anak-anak"
}));
console.log(withStatus);
// [
//   { nama: "Andi", umur: 25, status: "Dewasa" },
//   { nama: "Budi", umur: 30, status: "Dewasa" },
//   { nama: "Cici", umur: 22, status: "Dewasa" }
// ]

contoh kedua pakai pola ({ ...user, status: ... }), perhatikan kurungnya. arrow function yang ngembaliin object literal harus dibungkus kurung biasa, kalau nggak javascript bingung, ngira tanda kurawalnya itu body fungsi, hasilnya error atau nilai yang aneh.

...user itu spread operator, dia ngopy semua properti user yang lama ke object baru, baru ditambah status. dengan pola ini, array asli dan object-objectnya nggak ada yang berubah, semua salinan.

Format data dari database

contoh lain yang sering banget saya pakai, ngeformat data dari database biar siap ditampilkan:

const products = [
    { id: 1, name: "Laptop", price: 15000000 },
    { id: 2, name: "Mouse", price: 250000 },
    { id: 3, name: "Keyboard", price: 500000 }
];

// Format harga ke Rupiah
const formatted = products.map(p => ({
    ...p,
    priceFormatted: `Rp${p.price.toLocaleString("id-ID")}`
}));

console.log(formatted[0].priceFormatted); // Rp15.000.000

di sini map() nambah properti baru priceFormatted tanpa ngerusak properti aslinya. jadi data mentah dari database tetap utuh buat keperluan lain, dan versi yang sudah diformat dipakai buat tampilan.

2. Array filter buat nyaring data

filter() dipakai buat bikin array baru yang isinya cuma elemen yang memenuhi kondisi tertentu. kalau map() mentransformasi semuanya, filter() nyaring.

Sintaksnya mirip map

const arrayBaru = arrayAsli.filter((item, index, array) => {
    return kondisi; // true = disertakan, false = dilewati
});

callback filter() nerima parameter yang sama kayak map(), dan harus mengembalikan nilai truthy atau falsy. kalau hasilnya truthy, elemennya masuk ke array baru; kalau falsy, dilewati. panjang array hasilnya bisa sama, bisa kurang, tergantung berapa yang lolos.

Contoh Dasar

const angka = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const genap = angka.filter(item => item % 2 === 0);
console.log(genap); // [2, 4, 6, 8, 10]

const lebihDariLima = angka.filter(item => item > 5);
console.log(lebihDariLima); // [6, 7, 8, 9, 10]

item % 2 === 0 itu cek genap, item > 5 itu cek lebih dari lima. keliatan kan polanya? kondisinya bebas aja, yang penting hasilnya bisa dianggap true atau false.

filter juga bisa dipakai buat nyaring string, misalnya cari data yang mengandung kata tertentu:

const kata = ["apel", "jeruk", "alpukat", "pisang"];
const mulaiA = kata.filter(k => k.startsWith("a"));
console.log(mulaiA); // ["apel", "alpukat"]

Nyaring berdasarkan properti

ini pola yang paling sering kepake di aplikasi nyata, filter data berdasarkan properti:

const products = [
    { id: 1, name: "Laptop", price: 15000000, stock: 5 },
    { id: 2, name: "Mouse", price: 250000, stock: 0 },
    { id: 3, name: "Keyboard", price: 500000, stock: 10 },
    { id: 4, name: "Monitor", price: 3000000, stock: 0 }
];

// Produk yang tersedia (stock > 0)
const tersedia = products.filter(p => p.stock > 0);
console.log(tersedia);
// [
//   { id: 1, name: "Laptop", price: 15000000, stock: 5 },
//   { id: 3, name: "Keyboard", price: 500000, stock: 10 }
// ]

// Produk murah (harga di bawah 1 juta)
const murah = products.filter(p => p.price < 1000000);
console.log(murah);
// [
//   { id: 2, name: "Mouse", price: 250000, stock: 0 },
//   { id: 3, name: "Keyboard", price: 500000, stock: 10 }
// ]

dua filter di atas jalan di array yang sama tapi hasilnya beda-beda, sesuai kondisi masing-masing. ini yang bikin filter() fleksibel: satu sumber data, banyak cara pandang. apakah kalian perlu data yang udah urut berdasarkan harga juga? itu kerjaan sort(), bukan filter(), jangan sampai ketukar.

Trik hapus item dari array

filter() juga bisa dipakai buat “hapus” item dari array, dengan cara bikin array baru yang nggak menyertakan item yang mau dihapus:

let keranjang = [
    { id: 1, name: "Laptop", qty: 1 },
    { id: 2, name: "Mouse", qty: 2 },
    { id: 3, name: "Keyboard", qty: 1 }
];

// Hapus item dengan id = 2
keranjang = keranjang.filter(item => item.id !== 2);
console.log(keranjang);
// [
//   { id: 1, name: "Laptop", qty: 1 },
//   { id: 3, name: "Keyboard", qty: 1 }
// ]

ini teknik yang umum dipakai buat hapus data di state aplikasi, misalnya redux atau vuex. kondisinya item.id !== 2, jadi semua item yang id-nya bukan 2 dipertahankan, dan item id 2 tersaring keluar.

3. Array reduce buat akumulasi data

reduce() ini method paling fleksibel dari ketiganya. dia “mereduksi” array jadi satu nilai, bisa number, string, object, atau array baru. kalau map() dan filter() pekerjaannya jelas, reduce() ini kayak pisau serbaguna.

Sintaksnya agak beda

const hasil = array.reduce((accumulator, currentValue, index, array) => {
    return accumulatorBaru;
}, initialValue);

dua hal yang wajib dipahami: accumulator (sering disingkat acc) itu nilai yang dikumpulkan dari iterasi ke iterasi, dan initialValue itu nilai awal accumulator sebelum iterasi pertama. dua istilah ini yang bikin banyak orang males duluan sama reduce, padahal konsepnya sederhana.

cara kerjanya begini: tiap iterasi, acc berisi hasil dari iterasi sebelumnya, lalu callback ngitung nilai baru dan mengembalikannya, dan nilai itu yang jadi acc di iterasi berikutnya. setelah semua elemen habis, nilai acc terakhir itulah hasil akhirnya.

Contoh dasar: menjumlahkan angka

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

const total = angka.reduce((acc, curr) => acc + curr, 0);
console.log(total); // 15

kalau ditelusuri manual, jalannya begini:

  • mulai: acc = 0 (dari initialValue)
  • elemen 1: acc = 0 + 1 = 1
  • elemen 2: acc = 1 + 2 = 3
  • elemen 3: acc = 3 + 3 = 6
  • elemen 4: acc = 6 + 4 = 10
  • elemen 5: acc = 10 + 5 = 15

hasil akhirnya 15. bandingkan sama cara lama pakai forEach:

// Dengan forEach (cara lama):
let sum = 0;
angka.forEach(item => sum += item);
console.log(sum); // 15

dua-duanya sama hasilnya, cuma reduce() nggak butuh variabel sum di luar scope, semua akumulasinya dikelola di dalam method.

initialValue itu penting banget. kalau dikasih 0, hasilnya selalu number. kalau tidak dikasih, elemen pertama array dijadikan acc dan iterasi mulai dari elemen kedua. buat penjumlahan hasilnya sama aja, tapi buat kasus lain beda, dan bisa bikin error tersembunyi, misalnya array kosong bakal error TypeError: Reduce of empty array with no initial value. jadi saran saya, selalu kasih initialValue eksplisit.

Total harga keranjang

pola paling umum reduce() di aplikasi nyata, total belanja dari array of objects:

const keranjang = [
    { product: "Laptop", price: 15000000, qty: 1 },
    { product: "Mouse", price: 250000, qty: 2 },
    { product: "Keyboard", price: 500000, qty: 1 }
];

const totalBelanja = keranjang.reduce((acc, item) => {
    return acc + (item.price * item.qty);
}, 0);

console.log(`Rp${totalBelanja.toLocaleString("id-ID")}`);
// Rp16.000.000

di sini acc mulai dari 0, lalu tiap item dikaliin harga sama jumlahnya dulu baru ditambah ke acc. hasilnya total 16 juta.

Grouping data jadi object

reduce() juga jago buat ngerombak array jadi object, misalnya ngelompokkan data per kategori:

const students = [
    { name: "Andi", grade: "A" },
    { name: "Budi", grade: "B" },
    { name: "Cici", grade: "A" },
    { name: "Dedi", grade: "C" },
    { name: "Eka", grade: "B" }
];

const grouped = students.reduce((acc, student) => {
    // Jika grade belum ada, buat array baru
    if (!acc[student.grade]) {
        acc[student.grade] = [];
    }
    acc[student.grade].push(student.name);
    return acc;
}, {});

console.log(grouped);
// { A: ["Andi", "Cici"], B: ["Budi", "Eka"], C: ["Dedi"] }

di sini acc mulai dari {} (object kosong), bukan 0. tiap student, kalau grade-nya belum jadi key di object, bikin key baru dengan nilai array kosong, lalu dorong nama student ke array itu. hasilnya object yang mengelompokkan nama-nama per grade.

contoh ini nunjukin kenapa reduce() disebut paling fleksibel: hasilnya nggak harus number. dari array biasa, bisa jadi object terstruktur.

4. Method Array Lainnya

selain tiga besar di atas, ada beberapa method pendamping yang sering dipakai bareng:

forEach: Eksekusi per Elemen

const angka = [1, 2, 3];
angka.forEach(item => console.log(item)); // 1, 2, 3

forEach() menjalankan fungsi buat tiap elemen, tapi nggak ngembaliin apa-apa. pakai ini kalau tujuannya cuma efek samping, kayak log atau nulis ke layar, bukan buat dapat hasil baru.

find: Cari Satu Elemen

const users = [{ id: 1, name: "Andi" }, { id: 2, name: "Budi" }];
const user = users.find(u => u.id === 2);
console.log(user); // { id: 2, name: "Budi" }

find() ngembaliin elemen pertama yang cocok sama kondisi, atau undefined kalau nggak ada. beda sama filter yang ngembaliin semua yang cocok, find cuma satu.

some: Cek Apakah Ada

const angka = [1, 2, 3, 4, 5];
const adaGenap = angka.some(item => item % 2 === 0);
console.log(adaGenap); // true

some() ngembaliin true kalau minimal satu elemen memenuhi kondisi. cocok buat pertanyaan “apakah ada?”, misalnya cek apakah list sudah keisi.

every: Cek Semua

const semuaPositif = angka.every(item => item > 0);
console.log(semuaPositif); // true

kebalikannya, every() baru ngembaliin true kalau semua elemen memenuhi kondisi. satu aja yang nggak, hasilnya false.

aturan kasarnya: map buat transformasi, filter buat nyaring, reduce buat akumulasi, find buat cari satu, some/every buat cek, forEach buat efek samping.

5. Perbandingan Singkat

MethodMengembalikanJumlah HasilFungsi
map()Array baruSama dengan asliTransformasi setiap elemen
filter()Array baru0 sampai NSeleksi elemen yang memenuhi kondisi
reduce()Satu nilai (apa pun)1Akumulasi/menggabungkan semua elemen
find()Satu elemen0 atau 1Cari elemen pertama yang cocok
some()Booleantrue/falseApakah ada elemen yang memenuhi?
every()Booleantrue/falseApakah semua elemen memenuhi?

6. Studi Kasus: Dashboard Data

biar makin kebayang dipakai barengan, ini simulasi dashboard data transaksi:

const transaksi = [
    { id: 1, product: "Laptop", amount: 15000000, status: "selesai" },
    { id: 2, product: "Mouse", amount: 250000, status: "pending" },
    { id: 3, product: "Keyboard", amount: 500000, status: "selesai" },
    { id: 4, product: "Monitor", amount: 3000000, status: "batal" },
    { id: 5, product: "USB Hub", amount: 150000, status: "selesai" },
];

// Filter: transaksi selesai
const selesai = transaksi.filter(t => t.status === "selesai");

// Map: format untuk tampilan
const daftarSelesai = selesai.map(t => ({
    id: t.id,
    item: t.product,
    nominal: `Rp${t.amount.toLocaleString("id-ID")}`
}));

// Reduce: total pendapatan
const totalPendapatan = selesai.reduce((acc, t) => acc + t.amount, 0);

console.log("Daftar Transaksi Selesai:", daftarSelesai);
console.log("Total Pendapatan: Rp" + totalPendapatan.toLocaleString("id-ID"));

alurnya: filter() nyaring transaksi yang statusnya selesai, map() ngerapihin bentuknya buat tampilan (id, nama produk, nominal rupiah), dan reduce() ngitung total pendapatannya. tiga method, satu masalah, masing-masing pegang peran sendiri. ini pola yang persis saya pakai waktu bikin halaman laporan.

hasil di console bakal keliatan kayak gini:

Daftar Transaksi Selesai: [
  { id: 1, item: "Laptop", nominal: "Rp15.000.000" },
  { id: 3, item: "Keyboard", nominal: "Rp500.000" },
  { id: 5, item: "USB Hub", nominal: "Rp150.000" }
]
Total Pendapatan: Rp15.650.000

7. Chaining: gabungkan ketiganya

kekuatan sebenarnya dari map, filter, dan reduce itu bisa dirantai (chaining), pola yang paling sering saya pakai di project nyata, misalnya buat nyiapin data sebelum dirender ke tampilan:

const angka = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Ambil angka genap → kalikan 3 → jumlahkan
const hasil = angka
    .filter(n => n % 2 === 0)    // [2, 4, 6, 8, 10]
    .map(n => n * 3)              // [6, 12, 18, 24, 30]
    .reduce((acc, n) => acc + n, 0); // 90

console.log(hasil); // 90

kenapa bisa dirantai? karena filter() ngembaliin array, map() juga ngembaliin array, jadi hasilnya bisa langsung dipakai method berikutnya. urutannya kiri ke kanan: filter dulu buat nyusutin data, lalu map buat transformasi, dan reduce di ujung buat akumulasi.

penting buat efisiensi: filter duluan itu habit yang baik, karena data yang diteruskan ke map dan reduce jadi lebih sedikit, dan tiap method itu jalan satu iterasi penuh, bukan digabung jadi satu loop.

kalau ditulis pakai loop manual, kode di atas jadi panjang dan bercabang. dengan chaining, satu rangkaian yang dibaca dari atas ke bawah, maksudnya kebaca langsung.

Kesimpulan

map, filter, dan reduce adalah tiga array methods yang wajib dikuasai setiap developer javascript:

  • map(), transformasi setiap elemen array, hasilnya array baru dengan panjang sama
  • filter(), seleksi elemen berdasarkan kondisi, hasilnya array baru yang sudah disaring
  • reduce(), akumulasi array menjadi satu nilai apa pun, dari number sampai object

untungnya pakai method ini:

  • kode lebih deklaratif, fokus ke “apa yang ingin dicapai” bukan “bagaimana caranya”
  • tidak memutasi array asli (immutable)
  • bisa dirantai (chaining) buat operasi yang lebih kompleks
  • lebih gampang di-test dan di-debug

kuncinya latihan: ambil array apa pun yang kalian punya, coba transformasi pakai map, saring pakai filter, jumlahkan pakai reduce, dan lihat bedanya. begitu kebiasaan, ketiga method ini bakal kayak teman lama.

perbedaan var let const javascript belajar map reduce di javascript


Pertanyaan yang Sering Diajukan

Apa itu map di JavaScript?

map() adalah array method yang membuat array baru dengan mentransformasi setiap elemen array asli lewat sebuah fungsi. jumlah hasilnya sama dengan array aslinya.

Apa bedanya map dan forEach di JavaScript?

map() mengembalikan array baru hasil transformasi, sedangkan forEach cuma menjalankan fungsi untuk tiap elemen tanpa mengembalikan apa-apa. pakai map kalau hasilnya mau dipakai lagi.

Bagaimana cara filter array di JavaScript?

pakai filter() dengan fungsi kondisi, elemen yang kondisi-nya true akan disertakan di array baru. contohnya angka.filter(n => n % 2 === 0) buat ambil angka genap.

Kapan harus menggunakan reduce di JavaScript?

reduce() dipakai kalau array mau diringkas jadi satu nilai, misalnya total harga keranjang, atau mau dikelompokkan jadi object.

Kenapa reduce butuh initialValue?

initialValue jadi nilai awal accumulator. kalau tidak dikasih, elemen pertama array dijadikan accumulator dan iterasi mulai dari elemen kedua, ini bisa bikin jumlah atau tipe hasilnya tidak sesuai harapan.

Sigit Nurhanafi avatar
Full-stack developer & technical writer. Berpengalaman di PHP, Laravel, NodeJS, MySQL, dan Python. Aktif menulis tutorial pemrograman dan maintaining open-source projects di PemburuKode sejak 2021.