find, some, every, includes

Metode pencarian dan pengujian elemen array.

Daftar isi

Metode find, some, every, dan includes menguji isi array dan menjawab pertanyaan dengan keluaran yang berbeda, dari elemen, indeks, sampai jawaban ya atau tidak. Keempatnya memakai pola yang sama dengan map dan filter, yaitu menjalankan satu fungsi uji atas setiap elemen atau membandingkan satu nilai, dan semuanya berhenti lebih awal begitu jawabannya pasti. Topik ini membedah satu per satu, membandingkan keluaran kelimanya termasuk findIndex dalam satu tabel, lalu menimbang kapan some lebih tepat daripada filter yang dihitung panjangnya.

find dan findIndex#

Metode find mengembalikan elemen pertama yang lolos uji callback, dan undefined bila tidak ada satu pun yang lolos. Pencarian berhenti pada kecocokan pertama, sehingga elemen setelahnya tidak diproses lagi. Metode ini dipakai saat yang dicari hanya satu data, bukan sekumpulan data seperti pada filter.

js Contoh: find dan findIndex pada rak buku
const rak = [
  { judul: "Kamus Kecil", halaman: 210 },
  { judul: "Atlas Laut", halaman: 340 },
  { judul: "Panduan Tanaman", halaman: 180 },
];

const tebal = rak.find((b) => b.halaman > 300);
console.log(tebal);

const tidakAda = rak.find((b) => b.halaman > 1000);
console.log(tidakAda);

console.log(rak.findIndex((b) => b.halaman > 300));
console.log(rak.findIndex((b) => b.halaman > 1000));
text Keluaran
{ judul: 'Atlas Laut', halaman: 340 }
undefined
1
-1

Buku dengan lebih dari 300 halaman hanya satu, yaitu Atlas Laut, dan pencarian berhenti di situ walaupun elemen setelahnya belum diperiksa. Pencarian yang gagal mengembalikan undefined, bukan pesan error, sehingga hasilnya perlu diperiksa sebelum propertinya dibaca. Varian findIndex menjawab pertanyaan yang sama dengan posisinya, yaitu indeks 1 saat ditemukan dan -1 saat tidak ada, mengikuti kebiasaan metode pencarian array lainnya yang menjadikan -1 sebagai penanda tidak ditemukan.

some dan every#

Metode some menjawab apakah minimal satu elemen lolos uji, sedangkan every menjawab apakah seluruh elemen lolos. Keluaran keduanya selalu boolean, dan pengujian berhenti lebih awal, some pada kecocokan pertama, every pada kegagalan pertama. Keduanya dipakai untuk pemeriksaan cepat tanpa perlu menampung elemen yang lolos.

js Contoh: some dan every pada catatan suhu
const suhu = [24, 26, 29, 31, 27];

console.log(suhu.some((s) => s > 30));
console.log(suhu.every((s) => s > 20));
console.log(suhu.every((s) => s > 24));
text Keluaran
true
true
false

Nilai 31 membuat some langsung menjawab true tanpa memeriksa 27. Pernyataan “semuanya di atas 20” lolos pada kelima elemen, sedangkan “semuanya di atas 24” langsung gagal di elemen pertama yang bernilai 24. Pada array kosong, keduanya punya jawaban bawaan yang berbeda dan sering mengejutkan.

js Contoh: perilaku keduanya pada array kosong
const kosong = [];

console.log(kosong.some((s) => s > 30));
console.log(kosong.every((s) => s > 30));
text Keluaran
false
true

includes dan keanggotaan object#

Metode includes menguji keanggotaan satu nilai dengan perbandingan ketat, tanpa callback sama sekali. Bentuk ini paling pas untuk daftar nilai primitif seperti string dan angka, karena pertanyaannya sudah utuh, yaitu apakah nilai itu ada di dalam array. Keluarannya hanya true dan false, tanpa elemen yang ikut dikembalikan.

js Contoh: keanggotaan pada daftar piket
const piket = ["Ali", "Budi", "Citra"];

console.log(piket.includes("Budi"));
console.log(piket.includes("Dewi"));
text Keluaran
true
false

Masalah muncul pada array yang berisi object. includes membandingkan referensi, bukan isi propertinya, sehingga object literal yang mirip tidak pernah dianggap sama. Contoh berikut menyandingkan keduanya pada rak yang sama.

js Contoh: includes vs some untuk object
const rak = [
  { judul: "Atlas Laut", halaman: 340 },
  { judul: "Kamus Kecil", halaman: 210 },
];

const dicari = { judul: "Kamus Kecil", halaman: 210 };

console.log(rak.includes(dicari));
console.log(rak.some((b) => b.judul === "Kamus Kecil"));
text Keluaran
false
true

Variabel dicari adalah object baru yang letaknya di memori berbeda dari object di dalam array, walaupun propertinya persis sama, sehingga includes menjawab false. Untuk keanggotaan berdasarkan isi, some beserta syarat propertinya adalah alat yang tepat. Praktik yang lazim, primitif memakai includes, object memakai some.

Tabel perbandingan keluaran#

Kelima metode ini sering tertukar karena pola pemanggilannya mirip, padahal pertanyaannya dan bentuk keluarannya berbeda. Tabel berikut merangkum jawaban yang diberikan setiap metode pada keadaan cocok dan tidak cocok. Dengan satu tabel, pemilihan metode menjadi soal mencocokkan pertanyaan dengan bentuk jawabannya.

MetodeKeluaran bila cocokKeluaran bila tidak adaBerhenti pada
findelemen pertama yang lolosundefinedkecocokan pertama
findIndexindeks kecocokan pertama-1kecocokan pertama
sometruefalsekecocokan pertama
everytruefalsekegagalan pertama
includestruefalsekecocokan pertama

Cara memilihnya mengikuti bentuk data yang dibutuhkan. Bila elemen utuh dibutuhkan untuk diproses lebih lanjut, find adalah jawabannya, dan bila posisinya yang penting, misalnya untuk mengganti atau menghapus elemen itu, findIndex yang dipakai. Untuk keputusan ya atau tidak, pilih some bila syaratnya boleh dipenuhi sebagian, every bila syaratnya wajib dipenuhi semua, dan includes bila yang diuji sudah berupa satu nilai konkret.

js cek-rak-buku.js
// Pemeriksaan satu rak buku dengan find, some, every, dan includes
const rak = [
  { judul: "Kamus Kecil", kategori: ["referensi"], halaman: 210 },
  { judul: "Atlas Laut", kategori: ["peta", "geografi"], halaman: 340 },
  { judul: "Panduan Tanaman", kategori: ["geografi"], halaman: 180 },
];

const peta = rak.find((b) => b.kategori.includes("peta"));
console.log(`Buku peta: ${peta.judul}, ${peta.halaman} halaman`);

console.log(`Ada yang di bawah 200 halaman: ${rak.some((b) => b.halaman < 200)}`);
console.log(`Semua di bawah 400 halaman: ${rak.every((b) => b.halaman < 400)}`);
console.log(`Kategori geografi tersedia: ${rak.some((b) => b.kategori.includes("geografi"))}`);
text Keluaran
Buku peta: Atlas Laut, 340 halaman
Ada yang di bawah 200 halaman: true
Semua di bawah 400 halaman: true
Kategori geografi tersedia: true
bash
# jalankan berkas contoh dari direktori topik
node cek-rak-buku.js
text Keluaran
Buku peta: Atlas Laut, 340 halaman
Ada yang di bawah 200 halaman: true
Semua di bawah 400 halaman: true
Kategori geografi tersedia: true

Keluaran blok bash sama persis karena perintahnya menjalankan berkas yang sama. Berkas ini menyatukan keempat metode, find untuk mengambil satu buku, includes di dalam callback untuk menguji daftar kategori, some untuk pemeriksaan yang cukup satu kecocokan, dan every untuk syarat yang wajib dipenuhi semua buku. Empat kebutuhan berbeda itu terjawab tanpa satu perulangan manual pun.

some atau filter dengan length#

Pertanyaan “apakah ada yang belum selesai” sering dijawab dengan filter lalu menghitung panjang hasilnya. Cara ini benar tetapi boros, karena seluruh array baru dibangun hanya untuk dihitung lalu dibuang. Metode some menjawab pertanyaan yang sama, berhenti pada kecocokan pertama, dan menuliskan maksudnya lebih langsung.

js Contoh: filter dengan length vs some
const tugas = [
  { nama: "menyapu", selesai: true },
  { nama: "membersihkan papan", selesai: false },
  { nama: "menyiram tanaman", selesai: false },
];

const belumSelesai = tugas.filter((t) => !t.selesai).length;
console.log(belumSelesai > 0);

console.log(tugas.some((t) => !t.selesai));
text Keluaran
true
true

Kedua bentuk menghasilkan true, tetapi jalannya berbeda. filter memeriksa seluruh elemen dan menampung dua tugas yang belum selesai, sedangkan some berhenti pada tugas kedua. Bila daftar tugas yang lolos memang dibutuhkan untuk keperluan lain, filter tetap dipakai, dan panjangnya bisa jadi efek samping yang berguna. Bila pertanyaannya murni ada atau tidak ada, some menyatakan pertanyaan itu apa adanya.

Kesalahan umum#

  1. Memperlakukan undefined dari find sebagai data sah. Membaca properti dari hasil yang tidak ditemukan melempar error, misalnya hasil.judul pada undefined. Periksa hasilnya dengan if sebelum propertinya dibaca, dan gunakan filter untuk mendapatkan seluruh kecocokan karena find berhenti pada kecocokan pertama.
  2. Memakai includes untuk object. Perbandingannya berlaku pada referensi, bukan isi, sehingga object literal yang mirip selalu gagal ditemukan walaupun propertinya persis sama. Simpan includes untuk daftar string dan angka, dan gunakan some dengan syarat properti untuk data berbentuk object.
  3. Lupa perilaku every pada array kosong. Pemeriksaan “semua tugas valid” atas daftar yang masih kosong menghasilkan true, sehingga proses berikutnya berjalan padahal belum ada data. Tentukan dulu apakah daftar kosong boleh dianggap lolos, lalu tambahkan pemeriksaan length bila tidak boleh.
  4. Menulis syarat yang tidak konsisten menjawab ya atau tidak. Callback yang mengembalikan nilai lain, misalnya string kosong atau 0, tetap dinilai gagal karena aturan truthiness. Kembalikan perbandingan eksplisit seperti n >= 75 agar maksudnya terbaca dan tidak bergantung pada bentuk datanya.

Ringkasan#

  • find mengembalikan elemen pertama yang lolos uji atau undefined, sedangkan findIndex mengembalikan indeksnya atau -1.
  • some menjawab “ada yang lolos” dan every menjawab “semua lolos”, keduanya berhenti lebih awal begitu jawabannya pasti.
  • includes menguji keanggotaan nilai primitif dengan perbandingan ketat, sedangkan object diuji dengan some melalui propertinya.
  • Pada array kosong, some bernilai false dan every bernilai true.

Referensi#