Array.sort & reverse
Mengurutkan array: angka, string, dan object dengan comparator. Kamu akan paham kenapa sort() polos mengacaukan angka, cara menulis comparator yang benar, dan jebakan in-place yang diam-diam merusak data aslimu.
1. Analogi: Menyusun Kartu Nama
Bayangkan kamu memegang setumpuk kartu nama yang acak. Untuk menyusunnya rapi, kamu butuh ATURAN yang jelas: urut abjad A ke Z? Atau urut berdasarkan angka terbesar? Tanpa aturan, tiap orang menyusun dengan caranya sendiri dan hasilnya berantakan.
sort() di JavaScript punya masalah serupa: ia punya aturan bawaan yang sering tidak sesuai harapanmu. Makanya kamu harus paham aturan bawaannya, lalu menimpanya dengan aturanmu sendiri lewat comparator.
2. Kenapa sort() Polos Menyesatkan?
Coba tebak hasil kode ini:
const angka = [10, 5, 40, 1];
angka.sort();
console.log(angka); // [1, 10, 40, 5] ??? Hasilnya [1, 10, 40, 5], bukan [1, 5, 10, 40]. Kenapa? Karena sort() tanpa argumen mengubah SEMUA elemen menjadi string dulu, lalu membandingkannya karakter per karakter seperti di kamus. Sebagai string, "10" lebih kecil dari "5" karena karakter "1" lebih kecil dari "5". Urutan kamus, bukan urutan angka.
Ini bukan bug, ini memang spesifikasinya sejak JavaScript lahir. Untuk string, aturan ini pas. Untuk angka, aturan ini bencana. Solusinya: beri tahu sort aturan perbandinganmu sendiri lewat fungsi comparator.
3. Comparator: Aturan Mainnya
Comparator adalah fungsi (a, b) => ... yang dipanggil berulang-ulang oleh sort untuk tiap pasangan elemen. Aturannya sederhana:
- Return negatif (misal -1):
aditaruh SEBELUMb. - Return positif (misal 1):
aditaruh SESUDAHb. - Return 0: urutan keduanya tidak diubah.
Untuk angka, ada pola hafalan yang super praktis:
const angka = [10, 5, 40, 1];
angka.sort((a, b) => a - b); // [1, 5, 10, 40] menaik
angka.sort((a, b) => b - a); // [40, 10, 5, 1] menurunKenapa ini bekerja? Jika a lebih kecil dari b, maka a - b negatif, artinya a ditaruh duluan. Tepat seperti urutan menaik. Logika yang sama dibalik untuk menurun.
4. Contoh Bertahap: Sederhana ke Realistis
Contoh 1, string memang cocok dengan sort polos, tapi hati-hati huruf kapital:
const nama = ["Citra", "Andi", "Budi"];
nama.sort(); // ["Andi", "Budi", "Citra"] OK untuk string
// Untuk abjad yang benar-benar tepat (abaikan kapital):
const campur = ["citra", "Andi", "budi"];
campur.sort((a, b) => a.localeCompare(b));
console.log(campur); // ["Andi", "budi", "citra"]localeCompare adalah comparator bawaan khusus string yang paham aturan abjad manusia, termasuk huruf kapital dan karakter lokal.
Contoh 2 (realistis), leaderboard nilai siswa:
const siswa = [
{ nama: "Budi", nilai: 70 },
{ nama: "Andi", nilai: 90 },
{ nama: "Citra", nilai: 85 },
];
siswa.sort((x, y) => y.nilai - x.nilai);
console.log(siswa);
// Andi (90), Citra (85), Budi (70): nilai tertinggi duluPola ini dipakai di mana-mana: peringkat game, daftar produk termurah, komentar terbaru. Kuncinya selalu sama: bandingkan properti yang relevan di dalam comparator.
Contoh 3, reverse() membalik urutan:
const a = [1, 2, 3];
a.reverse();
console.log(a); // [3, 2, 1]5. Kesalahan Umum Pemula: SALAH vs BENAR
Kesalahan 1: sort angka tanpa comparator.
SALAH:
const harga = [100000, 25000, 9000];
harga.sort();
console.log(harga); // [100000, 25000, 9000] urutan kamus!BENAR:
harga.sort((a, b) => a - b); // [9000, 25000, 100000]Kesalahan 2: lupa bahwa sort MERUSAK array asli.
SALAH (data asli hilang tanpa sadar):
const nilaiAsli = [3, 1, 2];
const terurut = nilaiAsli.sort((a, b) => a - b);
console.log(nilaiAsli); // [1, 2, 3] ikut berubah!sort dan reverse bekerja in-place: mereka mengubah array-nya langsung, bukan membuat salinan. Kalau data aslinya masih dibutuhkan, salin dulu.
BENAR:
const nilaiAsli = [3, 1, 2];
const terurut = [...nilaiAsli].sort((a, b) => a - b);
console.log(nilaiAsli); // [3, 1, 2] tetap amanKesalahan 3: comparator me-return boolean, bukan angka.
SALAH: (a, b) => a > b (mengembalikan true/false, perilakunya tidak konsisten di semua engine).
BENAR: selalu kembalikan angka: (a, b) => a - b untuk angka, atau a.localeCompare(b) untuk string.
6. Ringkasan
sort() polos mengurutkan sebagai string, jadi untuk angka selalu pasang comparator (a, b) => a - b (menaik) atau (a, b) => b - a (menurun). Untuk string pakai localeCompare, untuk object bandingkan propertinya. Ingat: sort dan reverse mengubah array asli, jadi salin dulu dengan spread [...arr] kalau data aslinya masih dibutuhkan.
export default function App(): JSX.Element { return <h1>Hello world</h1> }
Tantangan
Peringkat Nilai
Diberi array siswa (nama, nilai). Urutkan dari nilai tertinggi, tampilkan peringkat: 1. Budi (95), dst. Fitur peringkat seperti ini adalah jantung aplikasi nyata: leaderboard game, klasemen turnamen, daftar produk terlaris, sampai ranking pencarian. Comparator yang benar memastikan urutannya tidak kacau saat datanya berupa angka.
<!doctype html> <html> <head> <meta charset="utf-8" /> </head> <body> <h1>Halo JS</h1> <p>Buka console preview untuk melihat output.</p> <script src="index.js"></script> </body> </html>