Home > Back-end >  Group of objects with similar names
Group of objects with similar names

Time:02-13

I have an object:

public class Student
{
  public int Id { get; set; }
  public string Name { get; set; }
}

I return a list that may look like the following:

var students = new List<Student>() { 
                new Student(){ Id = 1, Name="Bill85"},
                new Student(){ Id = 2, Name="Bill66"},
                new Student(){ Id = 3, Name="Ram7895"},
                new Student(){ Id = 4, Name="Ram5566"},
                new Student(){ Id = 5, Name="Join1230"}
            };

I want to group them together if they have similar names, to get the result like below, is there any quick way to solve this?

GroupStudentList
    UserList
        Id = 1, Name="Bill85"
        Id = 2, Name="Bill66"
    UserList
        Id = 3, Name="Ram7895"
        Id = 4, Name="Ram5566"
    UserList
        Id = 3, Name="Join1230"

CodePudding user response:

public class Student
{
 public List<Student> ListGroupStudent {get; set;}
 //add one list property...
}

var listGroup = listStudent.GroupBy(
    x => x.Name, 
    (key, y) => new { ListGroupStudent = y.ToList() });

CodePudding user response:

Making the assumption that similar names refers to identical names when all digits are removed from each name (as suggested by @klaus-gütter), a simple implementation could be the following:

  1. Group the students based on their Name, but stripped for digits (using Regex)
  2. For each group of similarily named students, select the students in that group to constitute a sublist

resulting in a nested List of Students:

List<List<Student>> groupStudentList = students
    .GroupBy(
        s => Regex.Replace(s.Name, "[0-9]*", string.Empty),
        (similarName, students) => students.ToList())
    .ToList();

The Regex expression above basically says "Replace all (if any) digits between 0 and 9 that exist in s.Name with an empty string". This means that if you have two students named "Tom1" and "T3o4m", they will also be grouped together -- because both names stripped for digits will be "Tom".


Optionally, you could create a UserList class:

public class UserList
{
    public List<Student> Students { get; set; }
}

and create a UserList object for each grouping of students based on their name similarity:

List<UserList> groupStudentList = students
    .GroupBy(
        s => Regex.Replace(s.Name, "[0-9]*", string.Empty),
        (similarName, students) => new UserList { Students = students.ToList() })
    .ToList();
  •  Tags:  
  • c#
  • Related