Jika Anda tidak ingin menambahkan pustaka MoreLinq ke proyek Anda hanya untuk mendapatkan DistinctBy
fungsionalitas maka Anda bisa mendapatkan hasil akhir yang sama menggunakan kelebihan Distinct
metode Linq yang membutuhkan IEqualityComparer
argumen.
Anda mulai dengan membuat kelas pembanding kesetaraan khusus generik yang menggunakan sintaks lambda untuk melakukan perbandingan kustom dua contoh kelas generik:
public class CustomEqualityComparer<T> : IEqualityComparer<T>
{
Func<T, T, bool> _comparison;
Func<T, int> _hashCodeFactory;
public CustomEqualityComparer(Func<T, T, bool> comparison, Func<T, int> hashCodeFactory)
{
_comparison = comparison;
_hashCodeFactory = hashCodeFactory;
}
public bool Equals(T x, T y)
{
return _comparison(x, y);
}
public int GetHashCode(T obj)
{
return _hashCodeFactory(obj);
}
}
Kemudian dalam kode utama Anda, Anda menggunakannya seperti ini:
Func<Person, Person, bool> areEqual = (p1, p2) => int.Equals(p1.Id, p2.Id);
Func<Person, int> getHashCode = (p) => p.Id.GetHashCode();
var query = people.Distinct(new CustomEqualityComparer<Person>(areEqual, getHashCode));
Voila! :)
Di atas mengasumsikan sebagai berikut:
- Properti
Person.Id
adalah tipeint
- The
people
koleksi tidak mengandung unsur nol
Jika koleksi dapat berisi nol maka cukup tulis ulang lambda untuk memeriksa nol, misalnya:
Func<Person, Person, bool> areEqual = (p1, p2) =>
{
return (p1 != null && p2 != null) ? int.Equals(p1.Id, p2.Id) : false;
};
EDIT
Pendekatan ini mirip dengan yang ada di jawaban Vladimir Nesterovsky tetapi lebih sederhana.
Ini juga mirip dengan yang ada di jawaban Joel tetapi memungkinkan untuk logika perbandingan kompleks yang melibatkan beberapa properti.
Namun, jika objek Anda hanya dapat berbeda Id
saat itu maka pengguna lain memberikan jawaban yang benar bahwa semua yang perlu Anda lakukan adalah mengesampingkan implementasi default dari GetHashCode()
dan Equals()
di Person
kelas Anda dan kemudian hanya menggunakan Distinct()
metode Linq out-of-the-box untuk menyaring duplikat.