Siti mengelola pendaftaran lokakarya komunitas. Form pendaftaran bisa terkirim dua kali oleh orang yang sama, dan daftar undangan dari kantor cabang datang membawa sebagian email yang sudah terdaftar. Dengan array, menjaga keunikan berarti memeriksa satu per satu — includes() sebelum setiap penambahan — dan membandingkan dua daftar berarti loop bersarang yang panjang.

Set menyelesaikan kedua pekerjaan itu sebagai aturan bawaan: sebuah Set hanya menyimpan nilai unik, pemeriksaan keanggotaan cukup dengan has(), dan sejak ECMAScript 2025 Set memiliki method perbandingan — union, intersection, difference — yang semuanya tersambung dan teruji berjalan di Node 24. Chapter ini menata daftar peserta Siti dengan Set, mengubahnya kembali menjadi array tanpa duplikat, lalu membandingkan dua daftar pendaftaran dengan method ES2025.

Aturan: Satu Nilai Hanya Muncul Sekali #

Aturan Set: dibuat dengan new Set(), diisi lewat add(nilai), dan setiap nilai yang sama hanya disimpan sekali. Di balik layar, Set memeriksa kesamaan nilai dengan aturan SameValueZero — aturan kesamaan yang sejalan dengan ===, dengan satu perbedaan: NaN dianggap sama dengan NaN sehingga tidak bisa menumpuk di satu Set. Urutan nilai mengikuti urutan penyisipan, dan size langsung memberi jumlah anggota:

js
const huruf = new Set(["a", "b", "a", "c"]);
console.log(huruf);
console.log(huruf.size);

Output yang Dihasilkan:

text
Set(3) { 'a', 'b', 'c' }
3

Constructor menerima iterable apa pun — di sini array empat string — dan menyaring duplikatnya saat konstruksi: nilai 'a' yang muncul dua kali hanya tersimpan sekali, sehingga size bernilai 3, bukan 4.

Kesamaan yang diukur tetap mengikuti aturan === untuk tipe referensi. Dua object literal dengan isi serupa tetap dihitung dua anggota berbeda karena identitasnya berbeda — keunikan Set bekerja pada nilai primitive secara langsung, dan pada object melalui referensinya.

Sisi lain yang berbeda dari array: anggota Set tidak punya posisi untuk diakses langsung. Tidak ada peserta[0] — membaca isi berarti menelusuri dengan for...of atau mengubahnya kembali menjadi array. Yang disediakan Set adalah pertanyaan keanggotaan (has), penambahan (add), penghapusan (delete), dan hitungan anggota (size) — dan keempatnya bekerja tanpa menyapu isi.

Daftar Peserta dalam Satu Berkas #

Operasi lengkap Set — add, has, delete, size, konversi ke array, sampai perbandingan antar daftar — dipakai bersama dalam satu berkas berikut. Siti menggabungkan dua jalur pendaftaran: array hasil form, dan Set dari daftar kantor:

// daftar-peserta.js
// Daftar peserta lokakarya: nilai unik, lalu perbandingan dua daftar.

const jalurForm = [
  "[email protected]",
  "[email protected]",
  "[email protected]",
  "[email protected]",
];
console.log(jalurForm.length);

const peserta = new Set(jalurForm);
console.log(peserta.size);
peserta.add("[email protected]");
peserta.add("[email protected]");
console.log(peserta.has("[email protected]"));
console.log(peserta.has("[email protected]"));
console.log(peserta.delete("[email protected]"));
console.log([...peserta]);

// Set methods ES2025: union, intersection, difference
const jalurKantor = new Set([
  "[email protected]",
  "[email protected]",
  "[email protected]",
]);
console.log(peserta.union(jalurKantor));
console.log(peserta.intersection(jalurKantor));
console.log(peserta.difference(jalurKantor));
console.log(jalurKantor.difference(peserta));

Output yang Dihasilkan:

Mari kita telaah baris-baris pentingnya:

  1. Baris 4–10 (jalurForm + length): array empat string dengan satu duplikat — email Siti muncul dua kali — sehingga length bernilai 4.
  2. Baris 12–13 (new Set(jalurForm)): duplikat tersaring saat konstruksi; size langsung 3.
  3. Baris 14–15 (peserta.add(...)): add("[email protected]") menambah anggota baru, sedangkan add("[email protected]") yang sudah ada tidak mengubah isi Set sama sekali.
  4. Baris 16–17 (peserta.has(...)): pemeriksaan keanggotaan menjawab true untuk Budi dan false untuk Adi yang belum terdaftar.
  5. Baris 18 (peserta.delete("[email protected]")): penghapusan mengembalikan true bila nilai ditemukan; Rina keluar dari daftar.
  6. Baris 19 ([...peserta]): spread mengubah Set kembali menjadi array — urutannya mengikuti urutan penyisipan.
  7. Baris 27 (peserta.union(jalurKantor)): gabungan kedua daftar tanpa duplikat menghasilkan Set(4) — empat email unik dari sembilan entri mentah.
  8. Baris 28 (peserta.intersection(jalurKantor)): hanya email yang terdaftar di kedua sisi yang lolos — Budi dan Dewi.
  9. Baris 29–30 (difference dua arah): peserta.difference(jalurKantor) menghasilkan Siti (ada di form, tidak di kantor), sedangkan arah sebaliknya menghasilkan Adi — difference tidak simetris, arah operand menentukan hasilnya.

Menghilangkan Duplikat Array #

Pola paling populer dari Set: mengubah array yang berisi duplikat menjadi array unik. Alurnya dua langkah — array menjadi Set (duplikat tersaring), lalu Set dikembalikan menjadi array lewat spread:

js
const angkaAcak = [1, 3, 3, 7, 1, 9];
const unik = [...new Set(angkaAcak)];
console.log(unik);
console.log(angkaAcak);

Output yang Dihasilkan:

text
[ 1, 3, 7, 9 ]
[ 1, 3, 3, 7, 1, 9 ]

Hasilnya array baru berisi angka unik, dan array asal tetap utuh. Alternatif yang setara adalah Array.from(new Set(angkaAcak)) — pilihlah salah satu yang paling terbaca bagi rekan tim, hasilnya identik.

Tanpa Set, penyaringan serupa ditulis sebagai loop yang memeriksa includes() pada array penampung sebelum setiap penambahan. Pemeriksaan semacam itu menyapu isi array dari depan untuk setiap elemen baru, sedangkan Set menyimpan keanggotaan sehingga pemeriksaan tidak menyapu apa pun. Untuk daftar besar yang sering diperiksa, perbedaannya terasa pada waktu proses — dan pada jumlah baris yang ditulis.

Membandingkan Dua Set #

union, intersection, dan difference hanyalah tiga dari tujuh method perbandingan ES2025. Method lain yang melengkapi kebutuhan keanggotaan:

MethodPertanyaan yang dijawab
a.union(b)nilai apa saja yang ada di a atau b
a.intersection(b)nilai apa saja yang ada di a dan b
a.difference(b)nilai a yang tidak ada di b
a.symmetricDifference(b)nilai yang hanya ada di salah satu sisi
a.isSubsetOf(b)apakah semua nilai a ada di b
a.isSupersetOf(b)apakah a memuat semua nilai b
a.isDisjointFrom(b)apakah a dan b tidak beririsan sama sekali

Dua method pemeriksaan mengembalikan nilai true/false, bukan Set baru — pas untuk dipakai langsung sebagai kondisi:

js
const menuUtama = new Set(["kopi", "teh"]);
const pesananKecil = new Set(["kopi"]);
console.log(pesananKecil.isSubsetOf(menuUtama));
console.log(menuUtama.isDisjointFrom(new Set(["gula"])));

Output yang Dihasilkan:

text
true
true

Pesanan kecil adalah subset dari menu utama, dan menu utama tidak beririsan dengan daftar bahan yang tidak dijual. Dengan tujuh method ini, perbandingan dua himpunan yang dulu ditulis sebagai loop bersarang kini cukup satu pemanggilan method.

Karena semua method perbandingan mengembalikan Set baru, hasilnya bisa langsung dilanjutkan: ditelusuri dengan for...of seperti chapter berikutnya, diubah ke array dengan spread, atau dijadikan operand method perbandingan lain. Urutan operand tetap perlu diperhatikan untuk difference — a.difference(b) dan b.difference(a) menjawab dua pertanyaan yang berbeda, sebagaimana terlihat pada rekap dua arah di berkas utama.

Set menuntaskan kebutuhan keunikan untuk nilai biasa. Ketika anggotanya adalah object besar yang siklus hidupnya dikelola bagian lain program, keunikan saja tidak cukup — pengelolaan memori ikut menentukan. Itulah wilayah kerja WeakMap dan WeakSet di chapter berikutnya.

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

daftar-peserta.js

Unduh berkas
javascript
// daftar-peserta.js
// Daftar peserta lokakarya: nilai unik, lalu perbandingan dua daftar.

const jalurForm = [
  "[email protected]",
  "[email protected]",
  "[email protected]",
  "[email protected]",
];
console.log(jalurForm.length);

const peserta = new Set(jalurForm);
console.log(peserta.size);
peserta.add("[email protected]");
peserta.add("[email protected]");
console.log(peserta.has("[email protected]"));
console.log(peserta.has("[email protected]"));
console.log(peserta.delete("[email protected]"));
console.log([...peserta]);

// Set methods ES2025: union, intersection, difference
const jalurKantor = new Set([
  "[email protected]",
  "[email protected]",
  "[email protected]",
]);
console.log(peserta.union(jalurKantor));
console.log(peserta.intersection(jalurKantor));
console.log(peserta.difference(jalurKantor));
console.log(jalurKantor.difference(peserta));