user2042721
user2042721

Reputation: 457

How do I find out the result from this C# code

//10 objects will be defined here
 Students s1 = new Students{};
 s1.id = 101;
 s1.name= "Andy";
 s1.subject = "BIS101";
 s1.score = 89;

 Students s2 = new Students{};
 s2.id = 101;
 s2.name= "Andy";
 s2.subject = "BIS102";
 s2.score = 95;

 Students s3 = new Students{};
 s3.id = 102;
 s3.name= "Katty";
 s3.subject = "BIS103";
 s3.score = 70;

 Students s4 = new Students{};
 s4.id = 103;
 s4.name= "Aimy";
 s4.subject = "BIS101";
 s4.score = 70;

 Students s5 = new Students{};
 s5.id = 104;
 s5.name= "Kody";
 s5.subject = "BIS102";
 s5.score = 60;

 Students s6 = new Students{};
 s6.id = 104;
 s6.name= "Kody";
 s6.subject = "BIS103";
 s6.score = 70;

 Students s7 = new Students{};
 s7.id = 103;
 s7.name= "Aimy";
 s7.subject = "BIS103";
 s7.score = 50;

 Students s8 = new Students{};
 s8.id = 102;
 s8.name= "Kathy";
 s8.subject = "BIS102";
 s8.score = 40;

 Students s9 = new Students{};
 s9.id = 105;
 s9.name= "Pretty";
 s9.subject = "BIS103";
 s9.score = 50;

 Students s10 = new Students{};
 s10.id = 105;
 s10.name= "Pretty";
 s10.subject = "BIS101";
 s10.score = 60;

         //create a new basket
 List<Students> list1 = new List<Students>();

 //add those objects into basket
 list1.Add(s1);list1.Add(s2);list1.Add(s3);list1.Add(s4);
 list1.Add(s5);list1.Add(s6);list1.Add(s7);list1.Add(s8);
 list1.Add(s9);list1.Add(s10);

From this code, how do I find out students who have enrolled for two courses?? I have been trying to sort this out and I am a newbie so I couldn't get any further.

Any help would be very much appreciated!

Thanks in advance!

Upvotes: 1

Views: 334

Answers (3)

Justin Niessner
Justin Niessner

Reputation: 245479

Here's a fairly simple LINQ query to find what you want:

list1.GroupBy(s => s.id).Where(s => s.Count() == 2);

Or, you could get there by looping:

var dict = new Dictionary<int, int>();
var matches = new List<int>();

foreach(var s in list1)
{
    if(dict.ContainsKey(s.id)) dict[s.id] = dict[s.id] + 1;
    else dict.Add(s.id, 1);
}

foreach(var kvp in dict)
{
    if(kvp.Value == 2) matches.Add(kvp.Key);
}

Keep in mind, though, that if two Student instances share an Id, they're really the same student. If that occurs, you may want to re-think your class structure. I would suggest something like:

public class Course
{
    public string Name { get; set; }
    public int Score { get; set; }
}

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Course> Courses { get; set; }
}

Which means that for any student, you would simply have to:

list1.Where(s => s.Courses.Length == 2);

Upvotes: 2

Alfonso Nava
Alfonso Nava

Reputation: 147

You have 2 ways of getting to the answer:

First you have to understand how to do what you need

You need to know students with at least 2 courses.
What you have is 10 Student objects that can refer to the same student but different course.
How you define the same student is in how many courses: you need to start counting that a single student have a Student Object with same ID or Name to identify it is the same Student and having a different course property; you can make a cycle for each of the Student objects.

Then have a "checklist": if you have not seen the name, then you add him to the list and count 1 course; if the name is different, then you add another name to the list and add 1 course to that name; if the name is already in your list, then you add 1 course to the name you are checking. After the 10 students your checklist will have Andy 2, Katty 2, Aimy 2, Kody 2, Pretty 2; then your you need to check your checklist and see for every element that if it has 2 or more courses to match your criteria.

When programming, try to separate your problem, see the what you have, what you need, and try to separate each step between as much as you can; these are called algorithms.

You can start with how you understand and then advance to best code options like, the last answers like Justin Niessner's (advanced answer):

list1.GroupBy(s => s.id).Where(s => s.Count() > 1);

You have your list (every student), it will be grouped by ids, so every element that have the same id will be "together", Where refers to a condition of what you need, the s.count refers to the elements that are together like "Pretty" that has the subject "BIS103" and "BIS101", the count of the elements is 2, so it match the Where(2 > 1) criteria

As you said you were a newbie I tried to explain it as I remember from school.

Upvotes: 2

Ben Reich
Ben Reich

Reputation: 16324

You can use Linq for this:

list1.GroupBy(s => s.id).Where(g => g.Count() == 2);

You should also consider redoing your class abstraction so that the Student object holds a list of courses. Your abstraction right now is confusing, since multiple instances of the Student class actually represent the same student.

I also recommend that you look at object and collection initialization syntax, which would help clean up this code a lot.

With the new abstraction and use of the initialization syntax, your instantation could look like:

var student1 = new Student { ID = 10, Courses = new List<Course> { c1, c2 } };
var students = new List<Student> { student1, student2 };

And then your Linq query would be:

students.Where(s => s.Courses.Count() == 2);

Upvotes: 2

Related Questions