Belajar dengan membaca secara berurutan

Mengurutkan dan Mencari — sort / find / some / every

Pelajari sort yang mengurutkan array lewat compare function, toSorted yang menjaga array asli, find dan findIndex yang mengembalikan 1 hasil, serta some dan every.

Kalau kamu mengurutkan daftar dengan loop for yang menukar posisi element, cara membandingkan dan langkah penukarannya harus kamu urus sendiri setiap kali. Mencari 1 item yang memenuhi kondisi juga berujung pada kode yang mirip: loop for dengan break untuk keluar begitu item-nya ditemukan.

Artikel ini membahas sort, yang mengurutkan array, dan find, yang mencari element yang memenuhi kondisi.

Menentukan Urutan dengan Function — sort dan Compare Function

Misalnya kamu ingin menampilkan daftar produk yang diurutkan dari harga termurah. Pengurutannya bisa dilakukan dengan method array, tapi kalau kamu hanya menulis products.sort(), hasilnya tidak urut berdasarkan harga, karena kamu belum memberi tahu apa yang harus dibandingkan.

sort (method yang mengurutkan element array) menerima compare function (function yang menerima 2 element dan mengembalikan number). Kalau 2 element yang diterimanya disebut a dan b, return value negatif menaruh a di depan, sedangkan return value positif menaruh b di depan. Kalau yang dikembalikan a.price - b.price, harganya urut dari kecil ke besar.

const products = [
  { name: "Mouse Wireless", price: 2980 },
  { name: "Power Bank", price: 4380 },
  { name: "Kabel USB-C", price: 980 },
  { name: "Mouse Pad", price: 2980 },
];

// Kalau hasil pengurangannya negatif, a di depan; kalau positif, b di depan
products.sort((a, b) => a.price - b.price);
console.log(products.map((item) => item.price).join(", "));  // 980, 2980, 2980, 4380

// Cek urutan 2 item yang harganya sama
console.log(products[1].name, products[2].name);             // Mouse Wireless Mouse Pad

// Kalau arah pengurangannya dibalik, urutannya jadi dari besar ke kecil
products.sort((a, b) => b.price - a.price);
console.log(products[0].name);                               // Power Bank
Number yang Dikembalikan Compare Function Menentukan Urutan
Compare functiona.price - b.pricea = 980b = 2980a = 2980b = 2980a = 4380b = 980-2000Hasilnya negatif0Tidak ada selisih3400Hasilnya positifa di depanUrutan aslitetapb di depan
Compare function yang sama mengembalikan number yang berbeda, tergantung harga 2 item yang diterimanya. 2 item yang selisihnya 0 tetap dalam urutan semula.

sort hanya melihat tanda (negatif atau positif) dari number yang dikembalikan, jadi -2000 dan -1 diperlakukan sama. Kalau kamu juga ingin mengatur urutan item yang harganya sama, tambahkan perbandingan value lain di dalam compare function untuk kasus selisihnya 0.

Urutkan daftar barang di aplikasi jual beli barang bekas sesuai urutan yang akan tampil di layar. listings sudah dideklarasikan.

① Urutkan berdasarkan jumlah karakter nama produk, dari yang paling pendek, lalu tampilkan nama produknya dengan digabung ", ".

② Urutkan berdasarkan harga, dari yang paling murah, lalu tampilkan nama produknya dengan cara yang sama.

③ Urutkan ulang berdasarkan harga, tapi kali ini barang yang harganya sama diurutkan dari jumlah like terbanyak, lalu tampilkan nama produknya dengan cara yang sama.

(Kalau kodenya berjalan dengan benar, penjelasan akan muncul.)

JavaScript / TypeScript Editor

Jalankan kode untuk melihat output

Memanggil sort Tanpa Argument — Perbandingan Bawaan dan toSorted

Misalnya kamu ingin mengurutkan array berisi lama waktu kunjungan halaman (dalam detik) dari yang paling singkat. Kalau kamu memanggil sort() tanpa compare function, hasilnya tidak urut menurut besar angkanya: 1180 detik malah muncul sebelum 25 detik.

Tanpa compare function, sort mengubah element-nya menjadi string dulu, lalu membandingkannya karakter demi karakter. 1180 diperlakukan sebagai "1180" dan 25 sebagai "25", jadi urutannya ditentukan oleh karakter pertama, 1 dan 2. sort mengurutkan array tempat ia dipanggil secara langsung, jadi kalau kamu juga ingin mempertahankan urutan aslinya, pakai toSorted (method yang mengembalikan array baru yang sudah diurutkan).

const viewSeconds = [1180, 980, 25, 4380];

// Tanpa compare function, element dibandingkan sebagai string
console.log(viewSeconds.sort().join(", "));                 // 1180, 25, 4380, 980

// Dengan compare function, element diurutkan menurut besar angkanya
console.log(viewSeconds.sort((a, b) => a - b).join(", "));  // 25, 980, 1180, 4380

// toSorted mengembalikan array baru dan tidak mengubah array asli
const stayTimes = [1180, 980, 25, 4380];
console.log(stayTimes.toSorted((a, b) => a - b).join(", "));  // 25, 980, 1180, 4380
console.log(stayTimes.join(", "));                            // 1180, 980, 25, 4380
Ada Tidaknya Compare Function Mengubah Apa yang Dibandingkan
Panggilsort()Number diubahmenjadi string1180 dan 25dibandingkan darikarakter pertama1180 tetapdi depanBerikan(a, b) => a - bDikurangkansebagai number1180 - 25bernilai positif25 pindahke depan
1180 dan 25 yang sama dibandingkan sebagai jenis value yang berbeda, tergantung apakah kamu memberikan compare function. Hasilnya, element yang berada di depan berbeda di kedua baris.

Begitu diubah menjadi string, "1180" pasti berada di depan "25", jadi berikan compare function saat mengurutkan array berisi number. sort kedua di kode atas mengurutkan lagi viewSeconds yang urutannya sudah diubah oleh sort pertama.

Pengaruh sort dan toSorted terhadap Array
viewSeconds.sort(...)Mengubaharray yang samaMengembalikanarray yang samaUrutan aslihilangstayTimes.toSorted(...)Array aslihanya dibacaMengembalikanarray baruUrutan aslitetap ada
Yang dikembalikan sort di baris atas adalah viewSeconds itu sendiri yang sudah diubah urutannya. Hanya toSorted yang membuat array baru.

Browser Lama Tidak Punya toSorted

toSorted ditambahkan ke spesifikasi di ES2023, dan di browser lama yang belum mendukungnya, baris yang memanggilnya berhenti karena TypeError. Supaya kodenya tetap berjalan di lingkungan seperti itu, panggil sort pada salinan array yang dibuat dengan spread syntax, seperti [...stayTimes].sort((a, b) => a - b).

Urutkan daftar ID member dan daftar jumlah stok, lalu tampilkan hasilnya. memberIds dan stockCounts sudah dideklarasikan.

① Urutkan memberIds tanpa memberikan compare function, lalu tampilkan dengan digabung ", ".

② Buat array baru dari stockCounts yang diurutkan tanpa compare function, lalu tampilkan dengan cara yang sama.

③ Buat array baru dari stockCounts yang diurutkan dari yang terkecil, lalu tampilkan dengan cara yang sama.

④ Tampilkan element pertama stockCounts.

JavaScript / TypeScript Editor

Jalankan kode untuk melihat output

Mengambil 1 Item yang Cocok — find dan findIndex

Misalnya kamu ingin mengambil 1 reservasi berdasarkan kode reservasinya. Kamu bisa memakai filter, tapi yang dikembalikan adalah array, jadi kamu harus menambahkan [0] untuk membaca item pertamanya, dan kalau tidak ada reservasi yang cocok, yang kembali adalah array kosong.

find (method yang mengembalikan element pertama yang memenuhi kondisi) mengembalikan element itu sendiri, yaitu element pertama yang membuat callback mengembalikan true. Kalau yang kamu butuhkan posisinya, pakai findIndex (method yang mengembalikan posisi element pertama yang memenuhi kondisi).

const reservations = [
  { code: "RSV-201", room: "Ruang Rapat A" },
  { code: "RSV-202", room: "Ruang Rapat B" },
  { code: "RSV-203", room: "Ruang Rapat C" },
];

// Mengembalikan element pertama yang membuat callback mengembalikan true
const target = reservations.find((item) => item.code === "RSV-202");
console.log(target.room);  // Ruang Rapat B

// Pakai findIndex kalau yang dibutuhkan posisinya
console.log(reservations.findIndex((item) => item.code === "RSV-202"));  // 1

// Kalau tidak ada reservasi yang cocok
console.log(reservations.find((item) => item.code === "RSV-999"));       // undefined
console.log(reservations.findIndex((item) => item.code === "RSV-999"));  // -1
Pemanggilan Berhenti Begitu Ada yang Cocok
Ke-1: RSV-201hasilnya falseLanjut keelement berikutnyaKe-2: RSV-202hasilnya trueElement inihasil findKe-3: RSV-203tidak dicekBerhenti mengeceksetelah item ke-2
Begitu callback mengembalikan true untuk item ke-2, callback tidak dipanggil lagi untuk item ke-3. Makin depan posisi element yang cocok, makin sedikit pemanggilannya.

find hanya mengembalikan item pertama yang cocok, jadi tidak bisa dipakai untuk mengumpulkan semua element yang cocok kalau jumlahnya lebih dari satu. Kalau semuanya dibutuhkan, pakai filter yang mengembalikan array; pakai find kalau 1 item sudah cukup.

Kalau Tidak Ditemukan, Hasilnya undefined

Kalau value yang dikembalikan find langsung kamu baca, seperti target.room, kodenya berhenti dengan TypeError: Cannot read properties of undefined (reading 'room') saat tidak ada element yang cocok. Cek dulu dengan if (target) sebelum membacanya.

Ambil 1 kupon dari daftar kupon yang sedang dibagikan berdasarkan kondisi tertentu. coupons sudah dideklarasikan, dan kupon yang expired-nya true sudah kedaluwarsa.

① Tampilkan persentase diskon kupon dengan kode MEMBER15.

② Tampilkan posisi (dihitung dari 0) kupon yang sudah kedaluwarsa.

③ Tampilkan kode kupon pertama yang belum kedaluwarsa.

④ Cari kupon dengan kode AUTUMN30, lalu tampilkan persentase diskonnya kalau ada, atau "Tidak ditemukan" kalau tidak ada.

JavaScript / TypeScript Editor

Jalankan kode untuk melihat output

Mengecek Seluruh Array dengan true atau false — some dan every

Misalnya kamu ingin mengecek stok untuk menentukan apakah semua barang dalam sebuah pesanan bisa dikirim sekaligus. Kamu bisa mengumpulkan barang yang stoknya habis dengan filter lalu menghitung jumlahnya, tapi yang kamu butuhkan bukan array, melainkan 1 jawaban: true atau false.

some (method yang mengembalikan true kalau minimal 1 element memenuhi kondisi) dan every (method yang mengembalikan true kalau semua element memenuhi kondisi) mengembalikan boolean, bukan element. Hasilnya bisa langsung dipakai sebagai kondisi if.

const orderItems = [
  { name: "Botol Isi Ulang", stock: 12 },
  { name: "Sabun Cuci Tangan", stock: 0 },
  { name: "Spons Mandi", stock: 5 },
];

// true kalau minimal 1 yang cocok
console.log(orderItems.some((item) => item.stock === 0));   // true

// true hanya kalau semuanya cocok
console.log(orderItems.every((item) => item.stock > 0));    // false

// Di array kosong, some bernilai false dan every bernilai true
console.log([].some((item) => item.stock > 0));             // false
console.log([].every((item) => item.stock > 0));            // true
Di Mana some dan every Berhenti Mengecek
Panggil some:cari stok 0Ke-1: 12hasilnya falseKe-2: 0hasilnya trueHasilnya true,sisanya dilewatiPanggil every:semua ada stok?Ke-1: 12hasilnya trueKe-2: 0hasilnya falseHasilnya false,sisanya dilewati
some maupun every sudah mendapat jawabannya di item ke-2, yang stoknya 0. every selesai begitu menemukan element yang tidak memenuhi kondisi.

Di array kosong, tidak ada element yang memenuhi kondisi, jadi some bernilai false; tidak ada juga element yang melanggar kondisi, jadi every bernilai true. Tabel di bawah merangkum value yang dikembalikan keempat method pencarian di artikel ini.

MethodYang dikembalikanKalau tidak ada element yang cocok
findElement pertama yang cocok itu sendiriundefined
findIndexPosisi element pertama yang cocok-1
sometrue kalau minimal 1 yang cocokfalse
everytrue kalau semuanya cocokfalse (true untuk array kosong)

Cek apakah semua peserta kursus online bisa mendapat sertifikat kelulusan, berdasarkan jumlah tugas yang dikumpulkan dan persentase kehadiran. learners sudah dideklarasikan.

① Tampilkan apakah semua peserta sudah mengumpulkan minimal 1 tugas.

② Tampilkan apakah ada peserta yang belum mengumpulkan tugas sama sekali.

③ Tampilkan nama peserta yang belum mengumpulkan tugas sama sekali.

④ Tampilkan apakah persentase kehadiran semua peserta 80% ke atas.

JavaScript / TypeScript Editor

Jalankan kode untuk melihat output
QUIZ

Cek Pemahaman

Jawab setiap pertanyaan satu per satu.

Soal 1Kalau compare function mengembalikan value negatif, element mana yang ditaruh sort di depan?

Soal 2Kalau kamu memanggil sort() pada [1180, 980, 25] tanpa compare function, urutan apa yang kamu dapat?

Soal 3Method mana yang dipakai untuk mengecek apakah semua jumlah stok bernilai 1 atau lebih, dengan hasil berupa 1 boolean?