Perbandingan dua daftar sering muncul dalam bentuk pertanyaan sederhana: siapa saja peserta yang mengikuti kedua kelas, dan mana yang hanya ada di salah satunya. Empat operator himpunan LINQ menjawab pertanyaan itu dengan membandingkan isi berdasarkan kesetaraan bawaan tipenya.
Empat Operator Himpunan #
Contoh berikut membandingkan dua daftar nomor peserta dan menghapus duplikat pada daftar nilai:
int[] kelasku = { 1, 2, 3, 4 };
int[] kelasmu = { 3, 4, 5, 6 };
int[] rapot = { 85, 60, 85, 90, 60 };
Console.WriteLine($"Union: {string.Join(" ", kelasku.Union(kelasmu))}");
Console.WriteLine($"Intersect: {string.Join(" ", kelasku.Intersect(kelasmu))}");
Console.WriteLine($"Except: {string.Join(" ", kelasku.Except(kelasmu))}");
Console.WriteLine($"Distinct: {string.Join(" ", rapot.Distinct())}");Output yang Dihasilkan:
Union: 1 2 3 4 5 6
Intersect: 3 4
Except: 1 2
Distinct: 85 60 90Mari kita bedah baris demi baris:
kelasku.Union(kelasmu): gabungan kedua urutan tanpa duplikat; elemen urutan pertama tampil lebih dulu, lalu elemen baru dari urutan kedua.kelasku.Intersect(kelasmu): irisan; hanya3dan4yang muncul di kedua daftar.kelasku.Except(kelasmu): selisih sisi kiri; elemenkelaskuyang tidak ada dikelasmu.rapot.Distinct(): duplikat dibuang; kemunculan pertama yang dipertahankan, sehingga urutan hasil mengikuti posisi pertama setiap nilai.
Kesetaraan dan Varian By #
Perbandingan memakai default equality comparer untuk tipe terkait. Karena record membandingkan isi, dua record Produk dengan nilai sama dianggap satu elemen, sehingga Distinct otomatis bekerja atas isinya; rincian kesetaraan record ada di bab Record Equality.
.NET 6 menambahkan varian DistinctBy, UnionBy, IntersectBy, dan ExceptBy yang membandingkan elemen lewat satu selector, misalnya produk.DistinctBy(p => p.Kategori). Gunakan varian ini agar tidak perlu menulis IEqualityComparer manual hanya untuk satu field.
Bila kesetaraan bawaan belum sesuai kebutuhan, setiap operator menerima IEqualityComparer<T> sebagai argumen tambahan. Di balik layar, operator-operator ini membangun hash set internal untuk membandingkan elemen, sehingga biayanya mendekati satu penelusuran sumber dan jauh lebih hemat daripada menyaring manual dengan loop bersarang. Semua operator himpunan juga bersifat deferred; perbandingan baru berjalan ketika hasilnya diiterasi. Perlu diingat, Except bersifat asimetris: kelasku.Except(kelasmu) menghasilkan 1 2, sedangkan kelasmu.Except(kelasku) menghasilkan 5 6, jadi urutan argumen menentukan sisi acuan.