开发者

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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜