Click here to Skip to main content
15,881,172 members
Articles / Programming Languages / C#

How to Use LINQ GroupBy

Rate me:
Please Sign up or sign in to vote.
2.86/5 (12 votes)
19 Apr 2009CPOL2 min read 360K   24   11
How to use the LINQ GroupBy feature.

The ‘GroupBy’ feature in LINQ is amazing and very powerful. When you use a ‘GroupBy’ in LINQ, internally, it calls an extension method which returns a sequence of System.Collections.Generic.IEnumerable<(Of <(IGrouping<(Of <(TKey, TSource>)>)>)>).

The GroupBy<(Of <(TSource, TKey>)>)(IEnumerable<(Of <(TSource>)>), Func<(Of <(TSource, TKey>)>)) method returns a collection of IGrouping<(Of <(TKey, TElement>)>) objects, one for each distinct key that was encountered. The key represents the attribute that is common to each value in the IGrouping<(Of <(TKey, TElement>)>) and can be accessed using a ForEach loop.

In order to understand GroupBy in LINQ, let’s take an example. Linda is an HR in a small private firm. To facilitate the HR process, she wants a simple console application to obtain some quick results. She needs the following details of employees:

  • Raw list of employees
  • List of employees grouped by the first letter of their first name
  • List of employees grouped by the year in which they were born
  • List of employees grouped by the year and month in which they were born
  • Total count of employees having birthdays in the same year
  • Sex ratio

Let’s take these requirements one by one and see how they can be easily achieved using ‘GroupBy’ in LINQ. We will first create a simple list of employees (List<Employees>) and add some data to it.

C#
class Program 
{ 
    static void Main(string[] args) 
    { 
        List<Employee> empList = new List<Employee>(); 
        empList.Add(new Employee() { ID = 1, FName = "John", MName = "", LName = "Shields", 
                                     DOB = DateTime.Parse("12/11/1971"), Sex = 'M' }); 
        empList.Add(new Employee() { ID = 2, FName = "Mary", 
                                     MName = "Matthew", LName = "Jacobs", 
                                     DOB = DateTime.Parse("01/17/1961"), Sex = 'F' }); 
        empList.Add(new Employee() { ID = 3, FName = "Amber", 
                                     MName = "Carl", LName = "Agar", 
                                     DOB = DateTime.Parse("12/23/1971"), Sex = 'M' }); 
        empList.Add(new Employee() { ID = 4, FName = "Kathy", MName = "", LName = "Berry", 
                                     DOB = DateTime.Parse("11/15/1976"), Sex = 'F' }); 
        empList.Add(new Employee() { ID = 5, FName = "Lena", 
                                     MName = "Ashco", LName = "Bilton", 
                                     DOB = DateTime.Parse("05/11/1978"), Sex = 'F' }); 
        empList.Add(new Employee() { ID = 6, FName = "Susanne", 
                                     MName = "", LName = "Buck", 
                                     DOB = DateTime.Parse("03/7/1965"), Sex = 'F' }); 
        empList.Add(new Employee() { ID = 7, FName = "Jim", MName = "", LName = "Brown", 
                                     DOB = DateTime.Parse("09/11/1972"), Sex = 'M' }); 
        empList.Add(new Employee() { ID = 8, FName = "Jane", MName = "G", LName = "Hooks", 
                                     DOB = DateTime.Parse("12/11/1972"), Sex = 'F' }); 
        empList.Add(new Employee() { ID = 9, FName = "Robert", MName = "", LName = "", 
                                     DOB = DateTime.Parse("06/28/1964"), Sex = 'M' }); 
        empList.Add(new Employee() { ID = 10, FName = "Cindy", MName = "Preston", 
                                     LName = "Fox", 
                                     DOB = DateTime.Parse("01/11/1978"), Sex = 'M' }); 

        // Printing the List 
        Console.WriteLine("\n{0,2} {1,7}    {2,8}      {3,8}      {4,23}      {5,3}", 
                          "ID", "FName", "MName", "LName", "DOB", "Sex"); 
        empList.ForEach(delegate(Employee e) 
        { 
            Console.WriteLine("{0,2} {1,7}    {2,8}      {3,8}      {4,23}    {5,3}", 
                              e.ID, e.FName, e.MName, e.LName, e.DOB, e.Sex); 
        }); 

        Console.ReadLine(); 

} 

class Employee 
{ 
    public int ID { get; set; } 
    public string FName { get; set; } 
    public string MName { get; set; } 
    public string LName { get; set; } 
    public DateTime DOB { get; set; } 
    public char Sex { get; set; } 
}

List of employees grouped by the first letter of their first name

To display a list of employees group by the first alphabet of their first name, use this query:

C#
// Group People by the First Letter of their FirstName 
var grpOrderedFirstLetter = empList.GroupBy(employees => 
    new String(employees.FName[0], 1)).OrderBy(employees => 
    employees.Key.ToString());; 

foreach (var employee in grpOrderedFirstLetter) 
{ 
    Console.WriteLine("\n'Employees having First Letter {0}':", 
                      employee.Key.ToString()); 
    foreach (var empl in employee) 
    { 
        Console.WriteLine(empl.FName); 
    } 
} 

Console.ReadLine();

List of employees grouped by the year in which they were born

In order to group the employees based on the year in which they were born, use this query:

C#
// Group People by the Year in which they were born            
var grpOrderedYr = empList.GroupBy(employees => 
    employees.DOB.Year).OrderBy(employees => employees.Key); 

foreach (var employee in grpOrderedYr) 
{ 
    Console.WriteLine("\nEmployees Born In the Year " + employee.Key); 
    foreach (var empl in employee) 
    { 
        Console.WriteLine("{0,2} {1,7}", empl.ID, empl.FName); 
               } 
} 
Console.ReadLine();

List of employees grouped by the year and month in which they were born

In order to group the employees based on the year and then the month in which they were born, use this query:

C#
// Group people by the Year and Month in which they were born 
var grpOrderedYrMon = empList.GroupBy(employees => 
    new DateTime(employees.DOB.Year, 
      employees.DOB.Month, 1)).OrderBy(employees => employees.Key); ; 

foreach (var employee in grpOrderedYrMon) 
{ 
    Console.WriteLine("\nEmployees Born in Year {0} - Month {1} is/are :", 
                      employee.Key.Year, employee.Key.Month); 
           foreach (var empl in employee) 
    { 
        Console.WriteLine("{0}: {1}", empl.ID, empl.FName); 
    } 
} 
Console.ReadLine();

Total number of birthdays each year

To get the total of the employees born in the same year, use this query:

C#
// Count people grouped by the Year in which they were born 
var grpCountYrMon = empList.GroupBy(employees => employees.DOB.Year) 
    .Select(lst => new {Year = lst.Key, Count = lst.Count()} ); 

foreach (var employee in grpCountYrMon) 
{ 
    Console.WriteLine("\n{0} were born in {1}", employee.Count, employee.Year);
} 
Console.ReadLine();

Sex ratio

To find the sex ratio in the company, use this query:

C#
// Sex Ratio 
var ratioSex = empList.GroupBy(ra => ra.Sex) 
  .Select( emp => new 
  { 
      Sex = emp.Key, 
      Ratio = (emp.Count() * 100) / empList.Count 
  }); 

foreach (var ratio in ratioSex) 
      { 
    Console.WriteLine("\n{0} are {1}%", ratio.Sex, ratio.Ratio); 
} 
Console.ReadLine();

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Winner - Best Mobile App - AT&T Developer Summit, Las Vegas, 2013

My personal resume can be found at: http://www.philippiercedeveloper.com

My game portfolio can be found at: http://www.rocketgamesmobile.com

About Philip Pierce:

I am a software developer with twenty years experience in game development, mobile, web, desktop, server, and database. My extensive background highlights an expertise in rapid application development using the latest Microsoft, Mobile, and Game Development technologies, along with the ability to create AI for games and business software, redesign existing software, develop multi-threaded software, and create client/server applications.

Comments and Discussions

 
GeneralMy vote of 1 Pin
Clifford Nelson16-May-18 10:52
Clifford Nelson16-May-18 10:52 
BugMissing a bracket to close Main Pin
WJM20125-May-13 10:59
WJM20125-May-13 10:59 
Bugbroken images Pin
WJM20125-May-13 10:53
WJM20125-May-13 10:53 
GeneralMy vote of 4 Pin
Soren.Persian23-Dec-12 18:28
professionalSoren.Persian23-Dec-12 18:28 
GeneralMy vote of 4 Pin
mostafizMonir3-Dec-12 18:56
mostafizMonir3-Dec-12 18:56 
Questionyour employees list made me feel young!! :) Pin
shay_e11-Sep-12 2:23
shay_e11-Sep-12 2:23 
GeneralMy vote of 1 Pin
aditya_bokade9-May-12 21:08
aditya_bokade9-May-12 21:08 
QuestionNice Job Pin
bvermilion4-Oct-11 12:58
bvermilion4-Oct-11 12:58 
GeneralMy vote of 3 Pin
Abolfazl Khusniddinov9-Mar-11 2:18
Abolfazl Khusniddinov9-Mar-11 2:18 
GeneralThank for the post and a Doubt Pin
itopaulo29-Aug-10 15:34
itopaulo29-Aug-10 15:34 
GeneralRe: Thank for the post and a Doubt Pin
Member 206690530-Sep-10 2:47
Member 206690530-Sep-10 2:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.