Linq lambda for searching a List within a List, finding a match, then deleting it from the list
I'm trying to learn Linq and I need help with a method that searches a List within a List, finds a match, and deletes it. For example, imagine I have a class called Student
:
public class Student
{
string FirstName;
string LastName;
}
Then imagine I have another class called Classroom
, which has a List<Student>
:
public class Classroom
{
List<Student> Students;
}
And finally, I have one more class, called School
, which has a list of Classrooms
:
public class School
{
List<Classroom> Classrooms;
}
Then, I need a method that takes in a Student
object, checks to see if the student is in the school, and deletes them if they are. If they're in the school, the method should delete them and return true. If they're not in the school, the method should return false and take no action. Here's an example using foreach loops, which I want to get rid of:
public bool RemoveStudentFromSchool(Student student)
{
foreach 开发者_Python百科(Classroom c in Classrooms)
{
foreach (Student s in c.Students)
{
if ((student.FirstName == s.FirstName) && (student.LastName == s.LastName))
{
s.Remove(student);
return true;
}
}
}
return false;
}
This assumes a student can only be in one room and Student
is IEquatable
on first and last name (or the references are equal):
var roomWithStudent = Classrooms.FirstOrDefault(c => c.Students.Any(s => s.Equals(student));
if (roomWithStudent != null)
{
roomWithStudent.Remove(student);
return true;
}
return false;
An alternative approach if Student
is not IEquatable
and the search object passed in is not necessarily the same reference:
var roomWithStudent = Classrooms
.SelectMany(c => c.Students.Select(s => new { Room = c, Student = s }))
.Where(rs => (student.FirstName == rs.Student.FirstName) && (student.LastName == rs.Student.LastName))
.FirstOrDefault();
if (roomWithStudent != null)
{
roomWithStudent.Room.Students.Remove(roomWithStudent.Student);
return true;
}
return false;
What about an extension method..
public static bool RemoveFromRoom(this Student student,School school)
{
if (student == null) throw new ArgumentNullException("student");
if (school == null) throw new ArgumentNullException("school");
bool ret = false;
var room = school.Classrooms.SingleOrDefault(cr=>cr.Students.Contains(student));
if (room !=null)
{
ret = true;
room.Students.Remove(student);
}
return ret;
}
Usage
student.RemoveFromRoom(instanceOfSchool);
Or...
public static bool RemoveStudentFromRoom(this School school,Student student)
{
if (student == null) throw new ArgumentNullException("student");
if (school == null) throw new ArgumentNullException("school");
bool ret = false;
var room = school.Classrooms.SingleOrDefault(cr=>cr.Students.Contains(student));
if (room !=null)
{
ret = true;
room.Students.Remove(student);
}
return ret;
}
Usage
instanceOfSchool.RemoveStudentFromRoom(student);
精彩评论