Страницы

Поиск по вопросам

среда, 29 января 2020 г.

Самый простой способ очистить List<T> от дубликатов по конкретной проперти

#c_sharp #list


например

List StudentsGroup = new List();

StudentsGroup.add(new Student(){Name="Vasia", Surname="Andrienko"});
StudentsGroup.add(new Student(){Name="Vasia", Surname="Potapenko"});
StudentsGroup.add(new Student(){Name="Fedia", Surname="Matsenko"});
StudentsGroup.add(new Student(){Name="Kolia", Surname="Mischenknko"});
StudentsGroup.add(new Student(){Name="Vasilisa", Surname="Vynnychenko"});
StudentsGroup.add(new Student(){Name="Vasilisa", Surname="Onoprienko"});


после очистки по Name должно выдать только следующие данные

{Name="Vasia", Surname="Andrienko"}//иль второго студента
{Name="Fedia", Surname="Matsenko"}
{Name="Kolia", Surname="Mischenknko"}
{Name="Vasilisa", Surname="Vynnychenko"}//иль второго студента

    


Ответы

Ответ 1



Без использования сторонних библиотек StudentsGroup = StudentsGroup.GroupBy(x => x.Name).Select(x => x.First()).ToList(); Взято с англоязычного SO

Ответ 2



Еще один вариант, воспользоваться перегрузкой Distinct, принимающей вторым параметром IEqualityComparer Например: class StudentComparer : IEqualityComparer { // Students are equal if their names are equal. public bool Equals(Student x, Student y) { //Check whether the compared objects reference the same data. if (Object.ReferenceEquals(x, y)) return true; //Check whether any of the compared objects is null. if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null)) return false; //Check whether the Student's properties are equal. return x.Name == y.Name; } // If Equals() returns true for a pair of objects // then GetHashCode() must return the same value for these objects. public int GetHashCode(Student student) { //Check whether the object is null if (Object.ReferenceEquals(student, null)) return 0; //Get hash code for the Name field if it is not null. return student.Name == null ? 0 : student.Name.GetHashCode(); } } Пример использования: IEnumerable noduplicates = StudentsGroup.Distinct(new StudentComparer());

Ответ 3



Можно воспользоваться перегрузкой метода Distinct, принимающей IEqualityComparer Вместо полной реализации IEqualityComparer можно делегировать все стандартной реализации, оставив себе только обращение к свойству Name: class StudentByNameComparer : IEqualityComparer { private readonly IEqualityComparer cmp; public StudentByNameComparer(IEqualityComparer cmp) { this.cmp = cmp; } public static StudentByNameComparer Default { get; } = new StudentByNameComparer(EqualityComparer.Default); // Также тут можно использовать StringComparer public bool Equals(Student x, Student y) => cmp.Equals(x?.Name, y?.Name); public int GetHashCode(Student x) => cmp.GetHashCode(x?.Name); } Пример использования: IEnumerable noduplicates = StudentsGroup.Distinct(StudentByNameComparer.Default);

Ответ 4



Если коллекцию формируете вы, и свойство для проверки всегда одно, используйте HashSet для этих целей, и дубликаты просто не добавятся. Не забудьте, что надо будет переопределить GetHashCode для составления хэша только по изменяющемуся свойству class Student { ... /// существующий код public override int GetHashCode() { unchecked { int hash = 13; // любое простое число return 13* Name.GetHashCode(); } } }

Комментариев нет:

Отправить комментарий