Reputation: 30388
I have a list of courses where the course object looks like this:
public class Course
{
public int Id { get; set; }
public string CourseName { get; set; }
public Teacher Teacher { get; set; } = new Teacher();
}
And for clarity, the teacher object looks like this:
public class Teacher
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
}
I'm trying to produce a list of unique teachers. I think I'm almost there but struggling to produce a List.
Here's what I have so far:
var teachers = from c in Courses // Courses is List<Course> with data in it
group c by new { c.Teacher.Id, c.Teacher.Name }
into uniqueTeachers
select uniqueTeachers.ToList();
Looks like the issue is that I need to create a Teacher object in the group by line.
What am I doing wrong here?
Upvotes: 0
Views: 294
Reputation: 52250
The first Select
gets a list of all teachers (non-unique). We then GroupBy
teacher ID and take the First
instance of Teacher in each group.
var teachers = courses.Select (a => a.Teacher)
.GroupBy(a => a.ID)
.Select (g => g.First()).ToList();
No IEqualityComparer
required.
LINQ? Why not PLINQ? Like, if you have a trillion courses, or something.
var teachers = new ConcurrentDictionary<int, Teacher>();
courses.AsParallel().ForAll(a => teachers.TryAdd(a.Teacher.ID, a.Teacher));
TryAdd
will fail (but not throw an exception) if the ID is already in the list, so this will give you the uniqueness. When the code is finished, you will have a dictionary with the ID and an object instance of each teacher. This solution uses multiple threads if it will increase performance.
IEqualityComparer
implementation not needed for this solution.
Upvotes: 1
Reputation: 38608
Like BradleyDotNET user commented, you have to implement the IEqualityComparar<T>
to take it done. For sample:
public class TeacherEqualityComparer : IEqualityComparer<Teacher>
{
public override bool Equals(Teacher x, Teacher y)
{
return x.Id == y.Id && x.Name == y.Name;
}
public override int GetHashCode((Teacher obj)
{
return obj == null ? 0 : obj.Id;
}
}
And try to use the Distinct
:
var teacherComparer = new TeacherEqualityComparer();
var teachers = (from c in Courses
select c.Teacher).Distinct(teacherComparer);
Upvotes: 2