Home > Net >  Linq: Edit GroupID of Students based on Common Interests
Linq: Edit GroupID of Students based on Common Interests

Time:08-17

I have a list of students with their subject of interests (separated by comma).

List<Students> students = new List<Students>(); 
                           
students.Add(new Students() { Name = "Krishna", GroupID= 0, Interests = "Physics,Maths" });

students.Add(new Students() { Name = "Ganesh", GroupID= 0, Interests = "History,Physics" });

students.Add(new Students() { Name = "Jayesh", GroupID= 0, Interests = "Tech,Humanity" });

students.Add(new Students() { Name = "Aditya", GroupID= 0, Interests = "Science"});

students.Add(new Students() { Name = "Ramesh", GroupID= 0, Interests = "Programming,Science"});

I want to use the Linq to edit the GroupID of students in the same list based on their common interests.

Expected Output:

GroupID 1; Students: Krishna, Ganesh (Reason: Common interest in Physics)

GroupID 2; Students: Aditya, Ramesh (Reason: Common interest in Science)

Any help is greatly appreciated.

Thank you so much!

CodePudding user response:

So first thing I did to solve this was create a dictionary of values to correspond to the interest. You can of course hard code these if you want, but I made them based on order they were found. I then processed your list and expanded it to group by the key value from dictionary and then reprocessed your students list to assign the group ids. I split things into methods for you to better see. Please view below. I think you will want to reconsider how you are grouping interest though. This will only work with 2 interest and if anyone overlaps you have no way to handle that with your current class. I think you might want to revisit your model first.

What I mean is what happens if say Krishna also had Tech as an interest. The code would overlap and give her a 3, and Ganesh a 1 still thus removing from group.

Before:

enter image description here

After:

enter image description here

void Main()
{
    List<Students> students = new List<Students>();

    students.Add(new Students() { Name = "Krishna", GroupID = 0, Interests = "Physics,Maths" });

    students.Add(new Students() { Name = "Ganesh", GroupID = 0, Interests = "History,Physics" });

    students.Add(new Students() { Name = "Jayesh", GroupID = 0, Interests = "Tech,Humanity" });

    students.Add(new Students() { Name = "Aditya", GroupID = 0, Interests = "Science" });

    students.Add(new Students() { Name = "Ramesh", GroupID = 0, Interests = "Programming,Science" });
    
    //students.Dump();
    
    CreateInterestDictionary(students);
    
    var studentsExpanded = ExpandStudents(students);
    
    var studentsGrouped = studentsExpanded.GroupBy(x => x.GroupID).Where(x => x.Count() > 1).ToList();
    studentsGrouped.ForEach(x =>
    {
        x.ToList().ForEach(y => {
            var student = students.Where(z => z.Name == y.Name).FirstOrDefault();
            student.GroupID = x.Key;
        });
    });
    
    //students.Dump();
}


public static Dictionary<string, int> InterestDict = new Dictionary<string, int>();
// You can define other methods, fields, classes and namespaces here
public class Students
{
    public string Name {get; set;}
    public int GroupID {get; set;}
    public string Interests {get; set;}
}

public static List<Students> ExpandStudents(List<Students> students)
{
    List<Students> studentsExpanded = new List<Students>();

    students.ForEach(x =>
    {
        if (x.Interests.Contains(","))
        {
            var interestSplit = x.Interests.Split(',');
            interestSplit.ToList().ForEach(y =>
            {
                studentsExpanded.Add(new Students() { Name = x.Name, GroupID = InterestDict[y], Interests = y });
            });
        }
        else
        {
            studentsExpanded.Add(new Students() { Name = x.Name, GroupID = InterestDict[x.Interests], Interests = x.Interests });
        }
    });
    
    return studentsExpanded;
}

public static Dictionary<string, int> CreateInterestDictionary(List<Students> students)
{
    var count = 1;
    students.ForEach(x =>
    {
        if (x.Interests.Contains(","))
        {
            var interestSplit = x.Interests.Split(',');
            interestSplit.ToList().ForEach(y =>
            {
                if (!InterestDict.ContainsKey(y))
                {
                    InterestDict.Add(y, count);
                    count  = 1;
                }

            });

        }
        else
        {
            if (!InterestDict.ContainsKey(x.Interests))
            {
                InterestDict.Add(x.Interests, count);
                count  = 1;
            }
        }
    });
    
    return InterestDict;
}

A potential issue though is your classes aren't really setup to handle if a student has an interest with more than 1 other student. For example:

what happens if say Krishna also had Tech as an interest. The code would overlap and give her a 3, and Ganesh a 1 still thus removing from group.

enter image description here

  • Related