Python

πŸ“Š JavaScript Array Methods: Panduan Lengkap

Kuasai semua Array methods yang penting di JavaScript β€” map, filter, reduce, find, some, every, sort, flatMap, dan teknik chaining dengan contoh kode mendalam

1. Overview Array Methods

Array adalah struktur data paling sering digunakan di JavaScript. JavaScript menyediakan puluhan built-in methods untuk memanipulasi array β€” mulai dari menambah/hapus elemen, mengubah urutan, mencari, memfilter, hingga mentransformasi data. Dalam tutorial ini, kita akan fokus pada transformation methods (map, filter, reduce, flatMap), search methods (find, findIndex, some, every, includes, indexOf), dan ordering methods (sort, reverse).

Kategori Array Methods

Kategori Methods Mengubah Asli? Return
Transformasimap, filter, reduce, flatMap❌ TidakArray / nilai baru
Pencarianfind, findIndex, some, every, includes, indexOf❌ TidakElemen / boolean / index
Urutansort, reverseβœ… YaArray yang diubah
Tambah/Hapuspush, pop, shift, unshift, spliceβœ… YaBeragam
Cetak/Buatjoin, slice, concat, Array.from, Array.of❌ TidakArray / string baru
Diagram: Data Flow Array Methods
  Input Array                Transform              Output Array
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ [1, 2, 3, 4] │─── map(x => x * 2) ────────▢│ [2, 4, 6, 8] β”‚
β”‚              │─── filter(x => x > 2) ──────▢│    [3, 4]    β”‚
β”‚              │─── reduce((a,b) => a+b) ────▢│      10      β”‚
β”‚              │─── find(x => x === 3) ──────▢│       3      β”‚
β”‚              │─── some(x => x > 3) ────────▢│     true     β”‚
β”‚              │─── every(x => x > 0) ───────▢│     true     β”‚
β”‚              │─── sort((a,b) => b-a) ──────▢│ [4, 3, 2, 1] β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       ↑                                                ↑
  Array asli                                    Array/nilai BARU
  TIDAK berubah (untuk map, filter, reduce)     (immutable pattern)

Immutable vs Mutable Methods

JavaScript β€” Immutable vs Mutable
// IMMUTABLE β€” tidak mengubah array asli, mengembalikan array/nilai baru
const angka = [3, 1, 4, 1, 5, 9];

const doubled = angka.map(x => x * 2);       // [6, 2, 8, 2, 10, 18]
const filtered = angka.filter(x => x > 3);   // [4, 5, 9]
const total = angka.reduce((a, b) => a + b); // 23
console.log(angka);  // [3, 1, 4, 1, 5, 9] ← TIDAK BERUBAH!

// MUTABLE β€” mengubah array asli
const buah = ["apel", "mangga", "jeruk"];

buah.push("pisang");    // Tambah di akhir β†’ array berubah!
buah.sort();            // Urutkan β†’ array berubah!
buah.reverse();         // Balik β†’ array berubah!
console.log(buah);  // ["pisang", "mangga", "jeruk", "apel"] ← BERUBAH!

// Best Practice: gunakan immutable methods sebisa mungkin
// Lebih aman, lebih mudah diprediksi, dan cocok untuk functional programming

2. map()

map() membuat array baru dengan menjalankan fungsi pada setiap elemen array asli. Ini adalah salah satu method yang paling sering digunakan di JavaScript modern β€” sempurna untuk mentransformasi data dari satu bentuk ke bentuk lain.

JavaScript β€” map()
// Sintaks: array.map(callback(element, index, array))
// Return: array BARU dengan hasil transformasi

// Contoh 1: Menggandakan setiap angka
const angka = [1, 2, 3, 4, 5];
const doubled = angka.map(x => x * 2);
console.log(doubled);  // [2, 4, 6, 8, 10]
console.log(angka);    // [1, 2, 3, 4, 5] ← tidak berubah

// Contoh 2: Transformasi string
const nama = ["budi", "andi", "citra"];
const kapital = nama.map(n => n.charAt(0).toUpperCase() + n.slice(1));
console.log(kapital);  // ["Budi", "Andi", "Citra"]

// Contoh 3: Mengambil properti tertentu dari array of objects
const produk = [
  { nama: "Laptop", harga: 15000000 },
  { nama: "Mouse", harga: 150000 },
  { nama: "Keyboard", harga: 350000 }
];
const namaProduk = produk.map(p => p.nama);
console.log(namaProduk);  // ["Laptop", "Mouse", "Keyboard"]

const hargaFormatted = produk.map(p => ({
  ...p,
  hargaFormatted: `Rp${p.harga.toLocaleString("id-ID")}`
}));
console.log(hargaFormatted);
// [{nama:"Laptop", harga:15000000, hargaFormatted:"Rp15.000.000"}, ...]

// Contoh 4: Membuat array of objects
const ids = [101, 102, 103];
const users = ids.map(id => ({
  id,
  name: `User_${id}`,
  active: true
}));
console.log(users);
// [{id:101, name:"User_101", active:true}, ...]

// Contoh 5: Menggunakan index dalam callback
const items = ["a", "b", "c", "d"];
const indexed = items.map((item, index) => `${index + 1}. ${item}`);
console.log(indexed);  // ["1. a", "2. b", "3. c", "4. d"]

// Contoh 6: Menggunakan dengan Promise (async map)
async function fetchAllUsers(ids) {
  const promises = ids.map(async id => {
    const res = await fetch(`/api/users/${id}`);
    return res.json();
  });
  return Promise.all(promises);
}
πŸ’‘ Tips

Arrow function dengan satu baris langsung mengembalikan nilai (tanpa return dan {}). Ini membuat kode map() sangat ringkas. Jika callback mengembalikan object literal, bungkus dengan (): items.map(item => ({ ... })) agar JavaScript tidak bingung dengan block scope.

3. filter()

filter() membuat array baru yang hanya berisi elemen-elemen yang lolos uji (callback mengembalikan true). Ini adalah cara paling efisien dan readable untuk memfilter data.

JavaScript β€” filter()
// Sintaks: array.filter(callback(element, index, array))
// Return: array BARU hanya dengan elemen yang lolos test

// Contoh 1: Filter angka genap
const angka = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const genap = angka.filter(x => x % 2 === 0);
console.log(genap);  // [2, 4, 6, 8, 10]

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

// Contoh 2: Filter array of objects
const mahasiswa = [
  { nama: "Budi", ipk: 3.5, aktif: true },
  { nama: "Andi", ipk: 2.8, aktif: false },
  { nama: "Citra", ipk: 3.9, aktif: true },
  { nama: "Dewi", ipk: 3.2, aktif: true },
  { nama: "Eka", ipk: 2.5, aktif: false }
];

const aktif = mahasiswa.filter(m => m.aktif);
console.log(aktif);  // Budi, Citra, Dewi

const cumLaude = mahasiswa.filter(m => m.ipk >= 3.5);
console.log(cumLaude);  // Budi, Citra

const aktifDanIPKTinggi = mahasiswa.filter(m => m.aktif && m.ipk >= 3.5);
console.log(aktifDanIPKTinggi);  // Budi, Citra

// Contoh 3: Filter string
const kata = ["apel", "anggur", "mangga", "alpukat", "jeruk"];
const diawaliA = kata.filter(k => k.startsWith("a"));
console.log(diawaliA);  // ["apel", "anggur", "alpukat"]

const panjangLebih5 = kata.filter(k => k.length > 5);
console.log(panjangLebih5);  // ["anggur", "mangga", "alpukat"]

// Contoh 4: Menghapus duplikat
const duplikat = [1, 2, 2, 3, 3, 3, 4, 4, 5];
const unik = duplikat.filter((item, index, arr) => arr.indexOf(item) === index);
console.log(unik);  // [1, 2, 3, 4, 5]

// Lebih simpel dengan Set:
const unikSet = [...new Set(duplikat)];
console.log(unikSet);  // [1, 2, 3, 4, 5]

// Contoh 5: Filter dengan multiple kondisi
function filterProduk(produk, criteria) {
  return produk.filter(p => {
    if (criteria.minHarga && p.harga < criteria.minHarga) return false;
    if (criteria.maxHarga && p.harga > criteria.maxHarga) return false;
    if (criteria.kategori && p.kategori !== criteria.kategori) return false;
    if (criteria.inStock && p.stok <= 0) return false;
    return true;
  });
}

const hasil = filterProduk(produk, {
  minHarga: 100000,
  maxHarga: 5000000,
  inStock: true
});

4. reduce()

reduce() adalah method yang paling powerful dan fleksibel di antara semua array methods. Ia "mereduksi" array menjadi satu nilai β€” bisa berupa angka, string, object, atau bahkan array lain. Hampir semua operasi array (map, filter, sum, group) bisa dilakukan dengan reduce().

JavaScript β€” reduce()
// Sintaks: array.reduce(callback(accumulator, element, index, array), initialValue)
// accumulator = hasil perhitungan sejauh ini
// element = elemen saat ini
// initialValue = nilai awal accumulator (opsional tapi DIREKOMENDASIKAN)

// Contoh 1: Jumlah semua angka
const angka = [1, 2, 3, 4, 5];
const total = angka.reduce((acc, curr) => acc + curr, 0);
console.log(total);  // 15

// Step-by-step:
// acc=0, curr=1 β†’ 0+1 = 1
// acc=1, curr=2 β†’ 1+2 = 3
// acc=3, curr=3 β†’ 3+3 = 6
// acc=6, curr=4 β†’ 6+4 = 10
// acc=10, curr=5 β†’ 10+5 = 15

// Contoh 2: Mencari nilai maksimum
const max = angka.reduce((acc, curr) => curr > acc ? curr : acc, angka[0]);
console.log(max);  // 5

// Contoh 3: Menghitung frekuensi kemunculan
const buah = ["apel", "mangga", "apel", "jeruk", "mangga", "apel"];
const frekuensi = buah.reduce((acc, item) => {
  acc[item] = (acc[item] || 0) + 1;
  return acc;
}, {});
console.log(frekuensi);  // { apel: 3, mangga: 2, jeruk: 1 }

// Contoh 4: Group by / Mengelompokkan data
const transaksi = [
  { item: "Laptop", kategori: "Elektronik", harga: 15000000 },
  { item: "Baju", kategori: "Fashion", harga: 250000 },
  { item: "Mouse", kategori: "Elektronik", harga: 150000 },
  { item: "Celana", kategori: "Fashion", harga: 300000 },
  { item: "Keyboard", kategori: "Elektronik", harga: 350000 }
];

const grouped = transaksi.reduce((acc, t) => {
  if (!acc[t.kategori]) acc[t.kategori] = [];
  acc[t.kategori].push(t);
  return acc;
}, {});
console.log(grouped);
// { Elektronik: [...3 items], Fashion: [...2 items] }

// Contoh 5: Flatten array (sebelum ada flat())
const nested = [[1, 2], [3, 4], [5, 6]];
const flat = nested.reduce((acc, arr) => acc.concat(arr), []);
console.log(flat);  // [1, 2, 3, 4, 5, 6]

// Contoh 6: Membuat pipeline (compose)
const pipeline = [
  (x) => x + 1,
  (x) => x * 2,
  (x) => x - 3
];
const hasilPipeline = pipeline.reduce((acc, fn) => fn(acc), 5);
console.log(hasilPipeline);  // ((5+1)*2)-3 = 9

// Contoh 7: Total harga per kategori
const totalPerKategori = transaksi.reduce((acc, t) => {
  acc[t.kategori] = (acc[t.kategori] || 0) + t.harga;
  return acc;
}, {});
console.log(totalPerKategori);
// { Elektronik: 15500000, Fashion: 550000 }

5. find() dan findIndex()

find() mengembalikan elemen PERTAMA yang memenuhi kondisi, sedangkan findIndex() mengembalikan index-nya. Keduanya berhenti mencari begitu menemukan kecocokan pertama (short-circuit), sehingga lebih efisien dari filter() jika Anda hanya butuh satu hasil.

JavaScript β€” find() & findIndex()
const produk = [
  { id: 1, nama: "Laptop", harga: 15000000, stok: 5 },
  { id: 2, nama: "Mouse", harga: 150000, stok: 0 },
  { id: 3, nama: "Keyboard", harga: 350000, stok: 12 },
  { id: 4, nama: "Monitor", harga: 3000000, stok: 3 },
  { id: 5, nama: "Mouse", harga: 250000, stok: 8 }
];

// find() β€” elemen pertama yang cocok
const laptop = produk.find(p => p.nama === "Laptop");
console.log(laptop);  // { id:1, nama:"Laptop", harga:15000000, stok:5 }

const mouseKosong = produk.find(p => p.nama === "Mouse" && p.stok === 0);
console.log(mouseKosong);  // { id:2, nama:"Mouse", ... }

const tidakAda = produk.find(p => p.nama === "Tablet");
console.log(tidakAda);  // undefined

// findIndex() β€” index elemen pertama yang cocok
const idxMonitor = produk.findIndex(p => p.nama === "Monitor");
console.log(idxMonitor);  // 3

const idxTidakAda = produk.findIndex(p => p.nama === "Tablet");
console.log(idxTidakAda);  // -1 (tidak ditemukan)

// Praktik: Update elemen berdasarkan ID
function updateProduk(id, changes) {
  const index = produk.findIndex(p => p.id === id);
  if (index !== -1) {
    produk[index] = { ...produk[index], ...changes };
    return true;
  }
  return false;
}
updateProduk(2, { stok: 10, harga: 1750000 });

// Praktik: Hapus elemen berdasarkan kondisi
function hapusProduk(id) {
  const index = produk.findIndex(p => p.id === id);
  if (index !== -1) {
    return produk.splice(index, 1)[0];
  }
  return null;
}

// find() vs filter()
// find() β†’ satu elemen pertama (atau undefined)
// filter() β†’ array semua yang cocok (bisa kosong [])
const semuaMouse = produk.filter(p => p.nama === "Mouse");
console.log(semuaMouse);  // [{id:2,...}, {id:5,...}]  ← semua mouse

const mousePertama = produk.find(p => p.nama === "Mouse");
console.log(mousePertama);  // {id:2,...}  ← hanya yang pertama

// includes() β€” cek apakah elemen ada (value equality)
const buah = ["apel", "mangga", "jeruk"];
console.log(buah.includes("mangga"));  // true
console.log(buah.includes("pisang"));  // false

// indexOf() β€” cari index elemen
console.log(buah.indexOf("jeruk"));    // 2
console.log(buah.indexOf("pisang"));   // -1

6. some() dan every()

some() mengecek apakah minimal satu elemen memenuhi kondisi (mengembalikan true). every() mengecek apakah semua elemen memenuhi kondisi. Keduanya adalah boolean methods β€” mengembalikan true atau false β€” dan menggunakan short-circuit evaluation untuk efisiensi.

JavaScript β€” some() & every()
const angka = [2, 4, 6, 8, 10];
const campur = [1, 2, 3, 4, 5];

// some() β€” apakah ADA yang genap?
console.log(angka.some(x => x % 2 === 0));    // true
console.log([1, 3, 5, 7].some(x => x % 2 === 0)); // false

// every() β€” apakah SEMUA genap?
console.log(angka.every(x => x % 2 === 0));   // true
console.log(campur.every(x => x % 2 === 0));  // false

// Contoh praktik: validasi form
const formData = {
  nama: "Budi Santoso",
  email: "budi@email.com",
  umur: 25,
  alamat: "Jl. Sudirman No. 123"
};

const requiredFields = ["nama", "email", "umur", "alamat"];
const isComplete = requiredFields.every(field => 
  formData[field] && formData[field].toString().trim() !== ""
);
console.log(isComplete);  // true

const adaKosong = requiredFields.some(field => 
  !formData[field] || formData[field].toString().trim() === ""
);
console.log(adaKosong);  // false

// Contoh: Cek apakah ada item kosong di keranjang
const keranjang = [
  { nama: "Laptop", qty: 1 },
  { nama: "Mouse", qty: 0 },    // qty 0!
  { nama: "Keyboard", qty: 2 }
];

const adaKosongQty = keranjang.some(item => item.qty === 0);
console.log(adaKosongQty);  // true

const semuaAdaQty = keranjang.every(item => item.qty > 0);
console.log(semuaAdaQty);  // false

// Contoh: Permission checking
const permissions = ["read", "write", "delete"];
const userPermissions = ["read", "write"];

const canDelete = userPermissions.includes("delete");
console.log(canDelete);  // false

const hasSomeAccess = permissions.some(p => userPermissions.includes(p));
console.log(hasSomeAccess);  // true

const hasFullAccess = permissions.every(p => userPermissions.includes(p));
console.log(hasFullAccess);  // false

// Short-circuit behavior
// some() berhenti saat menemukan true pertama
// every() berhenti saat menemukan false pertama
const besar = [10, 20, 30, 40, 50];
const adaDiAtas35 = besar.some(x => {
  console.log(`Cek ${x}`);  // Hanya cetak: Cek 10, Cek 20, Cek 30, Cek 40
  return x > 35;
});
// Berhenti di 40 karena sudah menemukan true!

7. sort()

sort() mengurutkan elemen array. Perlu diingat bahwa sort() mengubah array asli (mutating) dan secara default mengurutkan berdasarkan nilai Unicode (string), bukan numerik. Ini sering menjadi sumber kejutan bagi developer!

JavaScript β€” sort()
// ⚠️ DEFAULT sort mengubah array asli & mengurutkan sebagai STRING
const angka = [10, 5, 40, 25, 100, 1];
angka.sort();
console.log(angka);  // [1, 10, 100, 25, 40, 5] ← STRING sorting!

// βœ… Numeric sort dengan comparator function
const angka2 = [10, 5, 40, 25, 100, 1];

// Ascending (kecil ke besar)
angka2.sort((a, b) => a - b);
console.log(angka2);  // [1, 5, 10, 25, 40, 100]

// Descending (besar ke kecil)
angka2.sort((a, b) => b - a);
console.log(angka2);  // [100, 40, 25, 10, 5, 1]

// Immutable sort (tidak mengubah array asli)
const original = [30, 10, 50, 20, 40];
const sorted = [...original].sort((a, b) => a - b);
console.log(original);  // [30, 10, 50, 20, 40] ← tidak berubah!
console.log(sorted);    // [10, 20, 30, 40, 50]

// Sort array of objects
const produk = [
  { nama: "Laptop", harga: 15000000, rating: 4.5 },
  { nama: "Mouse", harga: 150000, rating: 4.8 },
  { nama: "Keyboard", harga: 350000, rating: 4.2 },
  { nama: "Monitor", harga: 3000000, rating: 4.7 }
];

// Sort berdasarkan harga (ascending)
const byHarga = [...produk].sort((a, b) => a.harga - b.harga);
console.log(byHarga.map(p => `${p.nama}: Rp${p.harga.toLocaleString()}`));
// "Mouse: Rp150.000", "Keyboard: Rp350.000", "Monitor: Rp3.000.000", "Laptop: Rp15.000.000"

// Sort berdasarkan rating (descending)
const byRating = [...produk].sort((a, b) => b.rating - a.rating);
console.log(byRating.map(p => `${p.nama}: ${p.rating}`));
// "Mouse: 4.8", "Monitor: 4.7", "Laptop: 4.5", "Keyboard: 4.2"

// Sort string (case-insensitive)
const nama = ["Charlie", "alice", "Bob", "diana"];
const sortedNama = [...nama].sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
console.log(sortedNama);  // ["alice", "Bob", "Charlie", "diana"]

// localeCompare untuk sorting bahasa Indonesia
const kota = ["Jakarta", "Bandung", "Surabaya", "Yogyakarta", "Semarang"];
const sortedKota = [...kota].sort((a, b) => a.localeCompare(b, "id"));
console.log(sortedKota);

// Multi-field sort
const siswa = [
  { nama: "Budi", kelas: "A", nilai: 85 },
  { nama: "Andi", kelas: "B", nilai: 90 },
  { nama: "Citra", kelas: "A", nilai: 90 },
  { nama: "Dewi", kelas: "B", nilai: 85 }
];

// Sort berdasarkan kelas ASC, lalu nilai DESC
const sortedSiswa = [...siswa].sort((a, b) => {
  if (a.kelas !== b.kelas) return a.kelas.localeCompare(b.kelas);
  return b.nilai - a.nilai;
});
console.log(sortedSiswa);
// Citra(A,90), Budi(A,85), Andi(B,90), Dewi(B,85)

8. flat() dan flatMap()

flat() membuat array baru dengan "meratakan" (flatten) nested array hingga kedalaman tertentu. flatMap() adalah gabungan dari map() diikuti flat(1) β€” sangat berguna ketika callback mengembalikan array dan Anda ingin hasilnya flat.

JavaScript β€” flat() & flatMap()
// ============================
// flat() β€” Meratakan nested array
// ============================

const nested1 = [[1, 2], [3, 4], [5, 6]];
console.log(nested1.flat());  // [1, 2, 3, 4, 5, 6]

const nested2 = [[1, [2, 3]], [4, [5, 6]]];
console.log(nested2.flat());      // [1, [2, 3], 4, [5, 6]] (1 level)
console.log(nested2.flat(2));     // [1, 2, 3, 4, 5, 6] (2 levels)
console.log(nested2.flat(Infinity)); // [1, 2, 3, 4, 5, 6] (semua level)

// Menghapus "lubang" (empty slots)
const berlubang = [1, 2, , 4, , 6];
console.log(berlubang.flat());  // [1, 2, 4, 6]

// ============================
// flatMap() β€” map + flat dalam satu langkah
// ============================

// Tanpa flatMap (2 langkah):
const kata = ["Hello World", "JavaScript Array"];
const kataPerBaris = kata.map(k => k.split(" "));     // [["Hello","World"],["JavaScript","Array"]]
const kataFlat = kataPerBaris.flat();                   // ["Hello","World","JavaScript","Array"]

// Dengan flatMap (1 langkah):
const kataFlatMap = kata.flatMap(k => k.split(" "));
console.log(kataFlatMap);  // ["Hello", "World", "JavaScript", "Array"]

// Contoh: Filter + Transform (flatMap melewatkan hasil kosong)
const pesanan = [
  { id: 1, items: ["Laptop", "Mouse"] },
  { id: 2, items: [] },  // Pesanan kosong
  { id: 3, items: ["Keyboard", "Monitor", "Speaker"] }
];

const semuaItems = pesanan.flatMap(p => p.items);
console.log(semuaItems);
// ["Laptop", "Mouse", "Keyboard", "Monitor", "Speaker"]
// (pesanan kosong otomatis dilewati!)

// Contoh: Split dan filter
const kalimat = "JavaScript adalah bahasa pemrograman yang populer";
const kataUnik = [...new Set(
  kalimat.toLowerCase().split(/\s+/).flatMap(k => k.split(""))
)];
console.log(kataUnik);

// Contoh: Membuat variasi data
const warna = ["merah", "biru"];
const ukuran = ["S", "M", "L"];
const kombinasi = warna.flatMap(w => ukuran.map(u => `${w}-${u}`));
console.log(kombinasi);
// ["merah-S", "merah-M", "merah-L", "biru-S", "biru-M", "biru-L"]

// Contoh: Extract tags dari posts
const posts = [
  { title: "Post 1", tags: ["javascript", "web"] },
  { title: "Post 2", tags: ["python", "data"] },
  { title: "Post 3", tags: ["javascript", "react"] }
];

const semuaTags = [...new Set(posts.flatMap(p => p.tags))];
console.log(semuaTags);  // ["javascript", "web", "python", "data", "react"]

// Count tag frequency
const tagCount = posts.flatMap(p => p.tags).reduce((acc, tag) => {
  acc[tag] = (acc[tag] || 0) + 1;
  return acc;
}, {});
console.log(tagCount);
// { javascript: 2, web: 1, python: 1, data: 1, react: 1 }

9. Method Chaining

Method chaining adalah teknik memanggil beberapa array methods secara berurutan dalam satu baris. Karena map(), filter(), sort() dll mengembalikan array baru, kita bisa langsung memanggil method berikutnya pada hasilnya. Ini membuat kode lebih deklaratif dan mudah dibaca β€” seperti membaca pipeline data.

JavaScript β€” Method Chaining
const produk = [
  { nama: "Laptop", harga: 15000000, kategori: "Elektronik", rating: 4.5, stok: 5 },
  { nama: "Mouse", harga: 150000, kategori: "Elektronik", rating: 4.8, stok: 0 },
  { nama: "Baju Kaos", harga: 120000, kategori: "Fashion", rating: 4.0, stok: 20 },
  { nama: "Keyboard", harga: 350000, kategori: "Elektronik", rating: 4.2, stok: 12 },
  { nama: "Celana Jeans", harga: 250000, kategori: "Fashion", rating: 4.6, stok: 8 },
  { nama: "Monitor", harga: 3000000, kategori: "Elektronik", rating: 4.7, stok: 3 },
  { nama: "Sepatu", harga: 500000, kategori: "Fashion", rating: 4.3, stok: 0 }
];

// Chain 1: Filter β†’ Map β†’ Sort
// Ambil nama produk elektronik yang tersedia, urutkan berdasarkan rating
const rekomendasi = produk
  .filter(p => p.kategori === "Elektronik" && p.stok > 0)
  .sort((a, b) => b.rating - a.rating)
  .map(p => ({ nama: p.nama, rating: p.rating }));

console.log(rekomendasi);
// [{nama:"Monitor", rating:4.7}, {nama:"Laptop", rating:4.5}, {nama:"Keyboard", rating:4.2}]

// Chain 2: Filter β†’ Map β†’ Reduce
// Hitung total nilai stok semua produk fashion
const totalNilaiStok = produk
  .filter(p => p.kategori === "Fashion")
  .map(p => p.harga * p.stok)
  .reduce((total, nilai) => total + nilai, 0);

console.log(`Total nilai stok Fashion: Rp${totalNilaiStok.toLocaleString()}`);
// Total nilai stok Fashion: Rp7.400.000

// Chain 3: Complex real-world example
// Analisis penjualan
const laporan = produk
  .filter(p => p.stok > 0)                          // Hanya yang tersedia
  .map(p => ({
    ...p,
    nilaiStok: p.harga * p.stok,
    status: p.stok <= 3 ? "Stok Rendah" : "Tersedia"
  }))
  .sort((a, b) => b.nilaiStok - a.nilaiStok)        // Urutkan by nilai
  .map(p => `${p.nama}: Rp${p.nilaiStok.toLocaleString()} (${p.status})`);

console.log("Laporan Inventaris:");
laporan.forEach(l => console.log(`  - ${l}`));

// Chain 4: Data transformation pipeline
const rawData = [
  { nama: "budi santoso", email: "BUDI@Email.com", umur: 25 },
  { nama: "andi prasetyo", email: "andi@email.com", umur: 17 },
  { nama: "citra dewi", email: "CITRA@email.com", umur: 30 },
  { nama: "dewi lestari", email: "", umur: 22 }
];

const cleanData = rawData
  .filter(d => d.email && d.umur >= 18)               // Validasi
  .map(d => ({
    nama: d.nama.split(" ").map(w =>                   // Capitalize nama
      w.charAt(0).toUpperCase() + w.slice(1)
    ).join(" "),
    email: d.email.toLowerCase().trim(),               // Normalize email
    umur: d.umur
  }))
  .sort((a, b) => a.nama.localeCompare(b.nama));       // Sort by nama

console.log(cleanData);
// [{nama:"Budi Santoso", email:"budi@email.com", umur:25},
//  {nama:"Citra Dewi", email:"citra@email.com", umur:30}]

// ⚠️ TIPS: Jangan terlalu panjang dalam satu chain!
// Jika chain lebih dari 3-4 methods, pertimbangkan untuk memecah
// menjadi beberapa variabel agar lebih mudah dibaca dan di-debug.

// ❌ Terlalu panjang:
// const result = data.filter(...).map(...).filter(...).sort(...).map(...).reduce(...);

// βœ… Lebih readable:
const filtered = data.filter(p => p.active);
const mapped = filtered.map(p => transform(p));
const sorted = mapped.sort(compareFn);
const result = sorted.reduce(reducer, {});
πŸ’‘ Tips

Method chaining membuat kode sangat deklaratif β€” Anda mendeskripsikan "apa yang dilakukan" bukan "bagaimana melakukannya". Namun, perhatikan performa: setiap method dalam chain membuat array baru. Untuk data sangat besar (jutaan elemen), pertimbangkan untuk menggunakan loop biasa atau library seperti Lodash yang mengoptimasi operasi ini.

10. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Array Methods:

Pertanyaan 1: Apa output dari [1,2,3].map(x => x * 2).filter(x => x > 3)?

a) [4, 6]
b) [2, 4, 6]
c) [3]
d) [1, 2, 3]

Pertanyaan 2: Apa output dari [1,2,3,4].reduce((acc, curr) => acc + curr, 0)?

a) "1234"
b) 10
c) [1, 2, 3, 4]
d) 24

Pertanyaan 3: Manakah yang MENGUBAH array asli?

a) map()
b) filter()
c) sort()
d) reduce()

Pertanyaan 4: Apa perbedaan antara find() dan filter()?

a) find() lebih lambat dari filter()
b) find() mengembalikan elemen pertama yang cocok, filter() mengembalikan array semua yang cocok
c) Tidak ada perbedaan
d) filter() mengembalikan satu elemen, find() mengembalikan array

Pertanyaan 5: Apa output dari [1, 10, 2, 20].sort()?

a) [1, 2, 10, 20]
b) [20, 10, 2, 1]
c) [1, 10, 2, 20]
d) [1, 2, 20, 10]
πŸ” Zoom
100%
🎨 Tema