Home > Net >  filter by list in an attribute that is also a list C#
filter by list in an attribute that is also a list C#

Time:09-29

I have a class named SchoolClass, which has a list of students as attribute. Then I have a search filter, in which I can search by a list of students and I have to return all the SchoolClasses where those students are part of their "list of students".

 public class SchoolClass
 {
    public List<string> students { get; set; }
 }

 List<string> searchedStudents = new List<string>
        { "Brian","Adrian","Matt","Chloe"};

So I have a list of SchoolClasses:

List<SchoolClass> schoolClasses = new List<SchoolClass>();

SchoolClass 1 ==>

//(it should return it because it matches Brian, one of the searchedStudents)
schoolClasses[0].students = { "Brian","Zara"}; 

SchoolClass 2 ==>

//(it shouldn't return it because there are no matches)
schoolClasses[1].students = { "Sophie","Zara"}; 

CodePudding user response:

i assume this is some sort of school work / project. please make sure that you actually understand the answer and learn some sort of lesson out of it! since this isnt a very data intense operation (with billions of entries) we can simply use go over the lists and search for the students. if you got huge amounts of data to go through, you should consider different data structures (eg. hashtables).

//polulate the list with data
SchoolClass schoolClass1 = new SchoolClass();
SchoolClass schoolClass2 = new SchoolClass();
SchoolClass schoolClass3 = new SchoolClass();

schoolClass1.students = new List<string> { "Brian", "Adrian", "Matt" };
schoolClass2.students = new List<string> { "Adrian", "Matt" };
schoolClass3.students = new List<string> { "Brian", "Matt", "Chloe" };

List<SchoolClass> schoolClasses = new List<SchoolClass>();
schoolClasses.Add(schoolClass1);
schoolClasses.Add(schoolClass2);
schoolClasses.Add(schoolClass3);

//set our filter
List<string> searchedStudents = new List<string> { "Brian", "Chloe" };

//filter the data by going over the lists
List<SchoolClass> classesWithSearchedStudents = new List<SchoolClass>();
for (int classIterator = 0; classIterator < schoolClasses.Count(); classIterator  )
{
    for (int filterIterator = 0; filterIterator < searchedStudents.Count(); filterIterator  )
    {
        //comparing with our filter and add class to the results list
        if (schoolClasses[classIterator].students.Contains(searchedStudents[filterIterator]))
        {
            classesWithSearchedStudents.Add(schoolClasses[classIterator]);
            break;
        }
    }
}

printResult(classesWithSearchedStudents);

just for demonstration, here is a more compact version using linq

var searchResult = new List<SchoolClass>();
foreach (var student in searchedStudents)
{
    searchResult.AddRange(schoolClasses.Where(x => x.students.Contains(student)));
}
searchResult = searchResult.Distinct().ToList();
printResult(searchResult);

for printing the answer, i used this function:

private static void printResult(List<SchoolClass> schoolClasses)
{
    for (int classIterator = 0; classIterator < schoolClasses.Count(); classIterator  )
    {
        Console.Write("found class with students: ");
        for (int studentIterator = 0; studentIterator < schoolClasses[classIterator].students.Count; studentIterator  )
        {
            Console.Write(schoolClasses[classIterator].students[studentIterator]   ", ");
        }
        Console.WriteLine();
    }
}

output:

found class with students: Brian, Adrian, Matt,

found class withstudents: Brian, Matt, Chloe,

CodePudding user response:

If I understand it correctly: You want to filter all schoolclasses that have "any" student from the filterlist in their student list.

If that assumption is correct than here you go.

Here's a simpeler and shorter function you can use. It has one less for loop and cuts off whenever it finds 1 of the students.

It looks through all classes and sees if "any" of the filtered students are in there".


public IEnumerable<SchoolClass> FindMatches(List<SchoolClass> schoolClasses, List<string> namesFilter)
{
    return schoolClasses.FindAll(schoolClass => schoolClass.students.Any(student => namesFilter.Contains(student)));

}

Obviously you can get the single line out of the method, but I thought I post it like this so you have an idea of the inputs and what the variable names actually are.

  • Related