2011-06-16 3 views
1

J'essaie d'apprendre Linq et j'ai besoin d'aide avec une méthode qui recherche une liste dans une liste, trouve une correspondance, et le supprime. Par exemple, imaginez que j'ai une classe appelée Student:Linq lambda pour rechercher une liste dans une liste, trouver une correspondance, puis la supprimer de la liste

public class Student 
{ 
    string FirstName; 
    string LastName; 
} 

Puis imaginez que j'ai une autre classe appelée Classroom, qui a une List<Student>:

public class Classroom 
{ 
    List<Student> Students; 
} 

Et enfin, j'ai une classe, appelée School , qui a une liste de Classrooms:

public class School 
{ 
    List<Classroom> Classrooms; 
} 

, je dois ensuite une méthode qui prend dans un Student objet, vérifie si l'étudiant est à l'école et les supprime s'ils le sont. S'ils sont à l'école, la méthode devrait les supprimer et retourner vrai. Si elles ne sont pas à l'école, la méthode devrait retourner false et ne rien faire. Voici un exemple en utilisant des boucles foreach, que je veux me débarrasser de:

public bool RemoveStudentFromSchool(Student student) 
{ 
    foreach (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; 
} 

Répondre

3

Cela suppose un étudiant ne peut être dans une chambre et Student est IEquatable sur le premier et le dernier nom (ou les références sont égaux):

var roomWithStudent = Classrooms.FirstOrDefault(c => c.Students.Any(s => s.Equals(student)); 
if (roomWithStudent != null) 
{ 
    roomWithStudent.Remove(student); 
    return true; 
} 
return false; 

Une autre approche si Student n'est pas IEquatable et l'objet de recherche est passé dans pas nécessairement la même référence:

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; 
+1

devrait plutôt être: Tous (s = > (student.FirstName == s.FirstName && student.LastName = = s.LastName)) – ub1k

+0

@ ub1k: Vous ne savez pas exactement ce que vous voulez dire - pouvez-vous élaborer? – ChrisWue

+0

@ ub1k chris mentionne que la première approche est avec IEquatable ce qui signifierait qu'il aurait dû faire sa propre implémentation de equals et gethashcode de toute façon – Manatherin

1

Qu'en est-il une méthode d'extension ..

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; 
} 

Utilisation

student.RemoveFromRoom(instanceOfSchool); 

Ou ...

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; 
} 

Utilisation

instanceOfSchool.RemoveStudentFromRoom(student); 
+0

+1, je vais en faire une méthode d'extension. Merci pour votre contribution. – Monochrome

Questions connexes