MulaiCode
JavaScript

JS Array Sorting

Pelajari cara mengurutkan array di JavaScript dengan berbagai metode dan teknik pengurutan.

JavaScript Sorting Arrays untuk Pemula

Pengurutan (sorting) adalah operasi penting dalam pemrograman, yang memungkinkan kita menyusun data secara teratur. JavaScript menyediakan beberapa metode bawaan untuk mengurutkan array dengan mudah dan efisien.

Mengapa Kita Butuh Pengurutan Array? 🤔

Array yang tidak terurut sulit untuk:

  • Dianalisis dan dipahami oleh pengguna
  • Dicari dengan efisien
  • Diproses dalam algoritma tertentu
  • Ditampilkan dalam antarmuka pengguna

Pengurutan membuat data lebih mudah diakses, dibaca, dan diolah!


1. Metode sort() Dasar

// Mengurutkan array string
const buah = ["Pisang", "Apel", "Mangga", "Jeruk"];
buah.sort();
console.log(buah); // Output: ["Apel", "Jeruk", "Mangga", "Pisang"]
 
// Mengurutkan array angka (perhatikan hasilnya!)
const angka = [40, 100, 1, 5, 25, 10];
angka.sort();
console.log(angka); // Output: [1, 10, 100, 25, 40, 5] (🚨 Tidak sesuai harapan!)

Penjelasan:

  • sort() mengurutkan elemen array dan mengubah array asli (mutating method)
  • Secara default, sort() mengurutkan elemen sebagai string
  • String diurutkan berdasarkan nilai karakter UTF-16
  • Untuk array string, hasilnya umumnya sesuai urutan alfabetis
  • Untuk array angka, hasilnya sering tidak sesuai harapan karena diurutkan sebagai string

⚠️ Perhatian: Secara default, [1, 10, 100, 25, 40, 5] diurutkan menjadi [1, 10, 100, 25, 40, 5] karena "10" lebih kecil dari "5" dalam perbandingan string.


2. Mengurutkan Array Angka dengan Benar

const angka = [40, 100, 1, 5, 25, 10];
 
// Menggunakan fungsi perbandingan (compare function)
angka.sort(function (a, b) {
  return a - b;
});
console.log(angka); // Output: [1, 5, 10, 25, 40, 100]
 
// Atau dengan arrow function (lebih ringkas)
const angka2 = [40, 100, 1, 5, 25, 10];
angka2.sort((a, b) => a - b);
console.log(angka2); // Output: [1, 5, 10, 25, 40, 100]
 
// Mengurutkan secara menurun (descending)
const angka3 = [40, 100, 1, 5, 25, 10];
angka3.sort((a, b) => b - a);
console.log(angka3); // Output: [100, 40, 25, 10, 5, 1]

Penjelasan:

  • Untuk mengurutkan angka dengan benar, kita perlu memberikan "compare function"
  • Compare function menerima dua argumen (a dan b) dan menentukan urutan mereka:
    • Jika hasilnya negatif, a ditempatkan sebelum b
    • Jika hasilnya positif, a ditempatkan setelah b
    • Jika hasilnya 0, urutan a dan b tidak berubah
  • a - b menghasilkan urutan naik (ascending)
  • b - a menghasilkan urutan turun (descending)

Keunggulan: Dengan compare function, kita bisa menentukan logika pengurutan kustom.


3. Mengurutkan Array Objek

const siswa = [
  { nama: "Budi", nilai: 85 },
  { nama: "Ani", nilai: 90 },
  { nama: "Dodi", nilai: 78 },
  { nama: "Siti", nilai: 95 },
];
 
// Mengurutkan berdasarkan nilai (tertinggi ke terendah)
siswa.sort((a, b) => b.nilai - a.nilai);
console.log(siswa[0]); // Output: { nama: "Siti", nilai: 95 }
console.log(siswa[siswa.length - 1]); // Output: { nama: "Dodi", nilai: 78 }
 
// Mengurutkan berdasarkan nama (A-Z)
siswa.sort((a, b) => {
  if (a.nama < b.nama) return -1;
  if (a.nama > b.nama) return 1;
  return 0;
});
console.log(siswa.map((s) => s.nama)); // Output: ["Ani", "Budi", "Dodi", "Siti"]
 
// Cara alternatif dengan localeCompare untuk string
siswa.sort((a, b) => a.nama.localeCompare(b.nama));
console.log(siswa.map((s) => s.nama)); // Output: ["Ani", "Budi", "Dodi", "Siti"]

Penjelasan:

  • Untuk mengurutkan array objek, kita perlu membandingkan properti tertentu dari objek
  • Untuk properti numerik seperti "nilai", kita bisa gunakan pengurangan sederhana
  • Untuk properti string seperti "nama", kita punya dua opsi:
    • Membandingkan string secara manual dengan if-else
    • Menggunakan metode localeCompare() yang lebih bersih dan mendukung bahasa internasional

Tip: localeCompare() sangat berguna untuk pengurutan teks dalam aplikasi multibahasa.


4. Metode reverse()

const buah = ["Apel", "Jeruk", "Mangga", "Pisang"];
 
// Membalik urutan array
buah.reverse();
console.log(buah); // Output: ["Pisang", "Mangga", "Jeruk", "Apel"]
 
// Kombinasi sort() dan reverse() untuk urutan Z-A
const nama = ["Budi", "Ani", "Dodi", "Siti"];
nama.sort();
nama.reverse();
console.log(nama); // Output: ["Siti", "Dodi", "Budi", "Ani"]
 
// Atau langsung dengan compare function
const angka = [1, 5, 10, 25, 40, 100];
angka.sort((a, b) => b - a); // Langsung descending
console.log(angka); // Output: [100, 40, 25, 10, 5, 1]

Penjelasan:

  • reverse() membalik urutan elemen dalam array
  • Seperti sort(), reverse() juga mengubah array asli (mutating method)
  • Kombinasi sort() dan reverse() bisa digunakan untuk pengurutan terbalik
  • Untuk pengurutan numerik descending, sort((a, b) => b - a) lebih efisien

5. Menyimpan Array Asli (Sorting tanpa Mutasi)

const angka = [40, 100, 1, 5, 25, 10];
 
// SALAH: Ini akan mengubah array asli
angka.sort((a, b) => a - b);
console.log("Array yang diubah:", angka); // [1, 5, 10, 25, 40, 100]
 
// BENAR: Membuat salinan terlebih dahulu dengan spread operator
const angkaAsli = [40, 100, 1, 5, 25, 10];
const angkaUrut = [...angkaAsli].sort((a, b) => a - b);
 
console.log("Array asli:", angkaAsli); // [40, 100, 1, 5, 25, 10]
console.log("Array terurut:", angkaUrut); // [1, 5, 10, 25, 40, 100]
 
// Alternatif dengan slice()
const angkaUrut2 = angkaAsli.slice().sort((a, b) => a - b);
console.log("Array asli masih sama:", angkaAsli); // [40, 100, 1, 5, 25, 10]
console.log("Hasil pengurutan:", angkaUrut2); // [1, 5, 10, 25, 40, 100]
 
// Menggunakan metode Array.from()
const angkaUrut3 = Array.from(angkaAsli).sort((a, b) => a - b);

Penjelasan:

  • sort() dan reverse() mengubah array asli, yang bisa jadi tidak diinginkan
  • Ada beberapa cara untuk mengurutkan tanpa mengubah array asli:
    • Menggunakan spread operator [...array]
    • Menggunakan slice() tanpa argumen untuk membuat salinan
    • Menggunakan Array.from(array)
  • Pendekatan ini penting dalam pemrograman fungsional dan ketika perlu mempertahankan data asli

6. Mengurutkan String dengan Sensitivitas Karakter

const kota = ["Jakarta", "bandung", "Surabaya", "aceh", "Yogyakarta"];
 
// Pengurutan default (case-sensitive)
kota.sort();
console.log(kota); // Output: ["Jakarta", "Surabaya", "Yogyakarta", "aceh", "bandung"]
 
// Pengurutan case-insensitive
kota.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
console.log(kota); // Output: ["aceh", "bandung", "Jakarta", "Surabaya", "Yogyakarta"]
 
// Pengurutan dengan localeCompare dan opsi
const kata = ["café", "cabo", "caña", "cafe", "cana"];
kata.sort((a, b) => a.localeCompare(b, "es", { sensitivity: "base" }));
console.log(kata); // Mengurutkan dengan benar sesuai aturan bahasa Spanyol

Penjelasan:

  • Pengurutan string default bersifat case-sensitive, huruf kapital muncul lebih dulu
  • Untuk pengurutan case-insensitive, kita bisa mengonversi string ke lowercase/uppercase
  • localeCompare() dapat menerima parameter tambahan:
    • Locale identifier (seperti 'en', 'id', 'es')
    • Opsi seperti { sensitivity: 'base' } untuk mengabaikan aksen dan kapitalisasi

Keunggulan: localeCompare() memungkinkan pengurutan yang benar untuk berbagai bahasa dan karakter khusus.


7. Algoritma Pengurutan Khusus

const angka = [40, 100, 1, 5, 25, 10];
 
// Mengurutkan secara acak (Fisher-Yates shuffle)
function acakArray(array) {
  const hasil = [...array];
 
  for (let i = hasil.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [hasil[i], hasil[j]] = [hasil[j], hasil[i]]; // Swap elemen
  }
 
  return hasil;
}
 
const angkaAcak = acakArray(angka);
console.log(angkaAcak); // Output: Array yang diacak
 
// Mengurutkan berdasarkan kedekatan dengan nilai tertentu
function urutBerdasarkanKedekatan(array, target) {
  return [...array].sort((a, b) => Math.abs(a - target) - Math.abs(b - target));
}
 
const dekatDengan20 = urutBerdasarkanKedekatan(angka, 20);
console.log(dekatDengan20); // Output: [25, 10, 40, 5, 1, 100] (diurutkan berdasarkan kedekatan dengan 20)

Penjelasan:

  • Kita bisa mengimplementasikan algoritma pengurutan khusus sesuai kebutuhan
  • Fisher-Yates shuffle adalah algoritma standar untuk mengacak array
  • Algoritma pengurutan berdasarkan kedekatan menunjukkan fleksibilitas compare function
  • Destructuring assignment [a, b] = [b, a] adalah cara modern untuk swap nilai di JavaScript

8. Performa dan Implementasi sort()

const banyakAngka = Array.from({ length: 1000 }, () =>
  Math.floor(Math.random() * 1000)
);
 
// Mengukur waktu pengurutan
console.time("Waktu pengurutan");
banyakAngka.sort((a, b) => a - b);
console.timeEnd("Waktu pengurutan");
 
// Sort dengan kondisi khusus - mengurutkan angka genap dulu, baru ganjil
const angka = [5, 8, 2, 7, 1, 6, 3, 4];
angka.sort((a, b) => {
  // Jika keduanya genap atau keduanya ganjil
  if (a % 2 === b % 2) {
    return a - b; // Urutkan normal
  }
  // Jika a genap dan b ganjil
  if (a % 2 === 0 && b % 2 === 1) {
    return -1; // a ditempatkan sebelum b
  }
  // Jika a ganjil dan b genap
  return 1; // a ditempatkan setelah b
});
 
console.log(angka); // Output: [2, 4, 6, 8, 1, 3, 5, 7]

Penjelasan:

  • Implementasi sort() di berbagai browser bisa berbeda
    • Beberapa menggunakan QuickSort, InsertionSort, MergeSort, atau kombinasi
    • Performa bisa berbeda tergantung jumlah dan jenis data
  • Compare function bisa sangat kompleks untuk logika pengurutan khusus
  • Gunakan console.time() dan console.timeEnd() untuk mengukur performa pengurutan

⚠️ Perhatian: Untuk dataset yang sangat besar, performa pengurutan bisa menjadi masalah penting.


9. Contoh Nyata: Mengurutkan Data Produk E-commerce

const produk = [
  { id: 1, nama: "Laptop Gaming", harga: 15000000, rating: 4.5, stok: 10 },
  { id: 2, nama: "Smartphone", harga: 5000000, rating: 4.8, stok: 25 },
  { id: 3, nama: "Headphone", harga: 1200000, rating: 4.2, stok: 8 },
  { id: 4, nama: "Monitor Ultrawide", harga: 8000000, rating: 4.7, stok: 0 },
  { id: 5, nama: "Keyboard Mechanical", harga: 2000000, rating: 4.6, stok: 15 },
];
 
// 1. Mengurutkan berdasarkan harga (terendah ke tertinggi)
function urutHargaTerendah(daftarProduk) {
  return [...daftarProduk].sort((a, b) => a.harga - b.harga);
}
 
// 2. Mengurutkan berdasarkan popularitas (rating tertinggi)
function urutTerpopuler(daftarProduk) {
  return [...daftarProduk].sort((a, b) => b.rating - a.rating);
}
 
// 3. Mengurutkan berdasarkan ketersediaan stok dan rating
function urutRekomendasi(daftarProduk) {
  return [...daftarProduk].sort((a, b) => {
    // Produk dengan stok 0 selalu di akhir
    if (a.stok === 0 && b.stok > 0) return 1;
    if (a.stok > 0 && b.stok === 0) return -1;
 
    // Jika keduanya tersedia atau keduanya habis, urutkan berdasarkan rating
    return b.rating - a.rating;
  });
}
 
// 4. Mengurutkan berdasarkan nama produk (A-Z)
function urutNama(daftarProduk) {
  return [...daftarProduk].sort((a, b) => a.nama.localeCompare(b.nama));
}
 
console.log("Termurah:", urutHargaTerendah(produk)[0].nama);
// Output: "Headphone"
 
console.log("Terpopuler:", urutTerpopuler(produk)[0].nama);
// Output: "Smartphone"
 
console.log(
  "Rekomendasi:",
  urutRekomendasi(produk).map((p) => p.nama)
);
// Output: ["Smartphone", "Keyboard Mechanical", "Laptop Gaming", "Headphone", "Monitor Ultrawide"]
 
console.log(
  "Urutan Abjad:",
  urutNama(produk).map((p) => p.nama)
);
// Output: ["Headphone", "Keyboard Mechanical", "Laptop Gaming", "Monitor Ultrawide", "Smartphone"]

Penjelasan:

Contoh di atas menunjukkan bagaimana pengurutan dapat diterapkan dalam skenario e-commerce:

  • Pengurutan berdasarkan harga untuk pencarian produk termurah/termahal
  • Pengurutan berdasarkan rating untuk menampilkan produk terpopuler
  • Pengurutan kompleks untuk rekomendasi yang memprioritaskan ketersediaan dan rating
  • Pengurutan alfabetis untuk kemudahan navigasi

Perhatikan bahwa setiap fungsi membuat salinan array untuk menghindari mutasi array asli, sehingga data produk asli tetap tidak berubah.


10. Tips untuk Pengurutan Array

Lakukan:

  • Gunakan compare function untuk mengurutkan angka atau objek
  • Pertimbangkan localeCompare() untuk pengurutan string multibahasa
  • Buat salinan array jika ingin mempertahankan urutan asli
  • Gunakan toSorted() (jika browser mendukung) untuk pengurutan non-mutasi
  • Tulis compare function yang jelas dan ringkas

Hindari:

  • Jangan gunakan sort() tanpa compare function untuk array angka
  • Hindari compare function yang kompleks dan sulit dibaca
  • Jangan mengandalkan urutan pengurutan untuk elemen yang sama nilainya (tidak stabil)
  • Jangan lupa bahwa sort() mengubah array asli

Latihan Singkat

Pertanyaan 1:

Apa output dari kode berikut?

const arr = [5, 2, 1, 10, 8];
arr.sort();
console.log(arr);

Petunjuk: Ingat bagaimana sort() bekerja secara default.

Jawaban: Output adalah [1, 10, 2, 5, 8] (diurutkan sebagai string, bukan angka)

Pertanyaan 2:

Bagaimana cara mengurutkan array objek berikut berdasarkan umur dari yang tertua ke termuda?

const orang = [
  { nama: "Ali", umur: 25 },
  { nama: "Budi", umur: 42 },
  { nama: "Cici", umur: 18 },
  { nama: "Dodi", umur: 33 },
];

Petunjuk: Gunakan compare function yang tepat.

Jawaban:

orang.sort((a, b) => b.umur - a.umur);
console.log(orang); // Output: Array dengan urutan Budi, Dodi, Ali, Cici