Grouping Data: Using Enumerable.GroupBy() Method
Published: 2020-09-15 23:05:31

 Grouping Data: Using Enumerable.GroupBy() Method

GroupBy() is one of the extension methods of System. Linq namespace. This method converts a collection into groups. It is used to group the elements of the dataset based on a specified key provided.  GroupBy() method provides value from each group in the collection. 
  
In this tutorial, we are going to see how to use GroupBy() to group data into different subgroups based on specific values of a property and we are also going to see an example code using  C# built-in methods like Substring() as criteria for grouping. In the end, we are going to use a user-defined method call as a key for grouping.

Example 1: Using Property value as a key
We are going to create a C# class called Student.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tutorial_Groupby
{
   public  class Student
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Province { get; set; }

       public string GetAgeGroup()
        {
            return this.Age < 13 ? "Children" : this.Age < 20 ? "Teenagers" : "Adults";
        }

      }
}

In the above code, we created a class called Student and its properties. The GetAgeGroup() method is only used in Example 3. It returns either Children or Teenagers or Adults which is used as a key by the GroupBy() method. In this example, we are going to use data inside the Students list to demonstrate how GroupBy() is implemented.



Out put of the above program:




//In Program.cs write the following code
using System;
using System.Collections.Generic;
using System.Linq;

namespace Tutorial_Groupby
{
    class Program
    {
        static void Main(string[] args)
        {
            /*Let's create a list of type Student called Students.
              Let's add instances of Student objects to the list*/
       List<Student> Students = new List<Student>()
        {
          new Student {Name = "James", Age = 19, Province = "AB"  },
          new Student { Name = "Robert", Age = 27, Province = "BC" },
          new Student { Name = "George", Age = 18, Province = "AB" },
          new Student { Name = "John", Age = 36, Province = "ON" },
          new Student { Name = "Peter", Age = 11, Province = "AB" },
          new Student {Name = "Lauren", Age = 25, Province = "SK"  },
          new Student { Name = "Jack", Age = 35, Province = "NU" },
          new Student { Name = "Henry", Age = 23, Province = "MB" },
          new Student { Name = "Bob", Age = 45, Province = "AB" },
          new Student { Name = "Wayne", Age = 11, Province = "AB" },
        };
          //We are grouping the list by their province which allows us to create sublists of the         main list Students.
         var studentsFromAlberta = Students.GroupBy(Student => Student.Province);
/*After assigning the sublist to a new variable using GroupBy() using province property as a key */      
         Console.WriteLine($"The total number of students from: {studentsFromAlberta.Count()}");
//group is a sublist with all students from same province
//https://csharp.net-tutorials.com/linq/grouping-data-the-groupby-method/
        foreach(var student in group)
        {
           Console.WriteLine("*" + student.Name);
        }
    }
}
}

First, we created instances of objects with the specified data inside the list of Students. We used the GroupBy() method to group all the entries based on the province property. GroupBy() method used province as a key to creating all the different students associated with a province. GroupBy() needs a key to base the grouping performed. In this case, we used the Province as the base for that.
Example 2: GroupBy() using built-in method Substring()
In this second example, we are going to use a C# built-in method Substring() to group the data in the students list above using province property.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Tutorial_GroupBy
{
    class Program
    {
        static void Main(string[] args)
        {
            /*Let's create a list of type Student called Students.
              Let's add instances of Student objects to the list*/
       List<Student> Students = new List<Student>()
        {
          new Student {Name = "James", Age = 19, Province = "AB"  },
          new Student { Name = "Robert", Age = 27, Province = "BC" },
          new Student { Name = "George", Age = 18, Province = "AB" },
          new Student { Name = "John", Age = 36, Province = "ON" },
          new Student { Name = "Peter", Age = 11, Province = "AB" },
          new Student {Name = "Lauren", Age = 25, Province = "SK"  },
          new Student { Name = "Jack", Age = 35, Province = "NU" },
          new Student { Name = "Henry", Age = 23, Province = "MB" },
          new Student { Name = "Bob", Age = 45, Province = "AB" },
          new Student { Name = "Wayne", Age = 11, Province = "AB" },
        };
    var studentsGroupByFirstLetter = Students.GroupBy(Student => Student.Name.Substring(0, 1));
            foreach (var group in studentsGroupByFirstLetter)
            {
                Console.WriteLine();
                Console.WriteLine("--------------------------------------------");
                Console.WriteLine("Students whose name start with " + group.Key + ":");
                //student is each student grouped according their first letter i.e all students whose name start in same letter will be
                //in the same sublist
                foreach (var student in group)
                {
                    Console.WriteLine("*" + student.Name);
                }
            }
}
}
In the above example GroupBy() used a C# built-in Substring() method’s return as a base for grouping. We can use almost anything inside the GroupBy that has a value as a parameter

Example 3: GroupBy() using user-defined methods
In this example, we have a method called GetAgeGroup() in the Student.cs which returns three different categories of ages the students are in. The method returns either Teenager, or Adult or Children. We will call the method from the inside GroupBy() to use the age categories as a base for grouping. GetAgeGroup() method is added in the Student.cs class.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Tutorial_GroupBy
{
    class Program
    {
        static void Main(string[] args)
        {
       List<Student> Students = new List<Student>()
        {
          new Student {Name = "James", Age = 19, Province = "AB"  },
          new Student { Name = "Robert", Age = 27, Province = "BC" },
          new Student { Name = "George", Age = 18, Province = "AB" },
          new Student { Name = "John", Age = 36, Province = "ON" },
          new Student { Name = "Peter", Age = 11, Province = "AB" },
          new Student {Name = "Lauren", Age = 25, Province = "SK"  },
          new Student { Name = "Jack", Age = 35, Province = "NU" },
          new Student { Name = "Henry", Age = 23, Province = "MB" },
          new Student { Name = "Bob", Age = 45, Province = "AB" },
          new Student { Name = "Wayne", Age = 11, Province = "AB" },
        };
            var studentsGroupByAge = Students.GroupBy(Student => Student.GetAgeGroup());
            foreach (var group in studentsGroupByAge)
            {
                Console.WriteLine();
                Console.WriteLine("--------------------------------------------");
                Console.WriteLine("Students who are " + group.Key + ":");
                //student is each student with same age group i.e all students whose age group is              same will be in the same sublist
                //in the same sublist
                foreach (var student in group)
                {
                    Console.WriteLine("*" + student.Name);
                }
            }
        }
    }
}

In the above example Code the result of the method call is used as a key for grouping. All students at the same age group according to the GetAgeGroup() method are then grouped together.

Example 4: GroupBy() Using Composite-Keys
In this last example we are using more than one keys to use as a base for the grouping inside the GroupBy() method.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Tutorial_Groupby
{
    class Program
    {
        static void Main(string[] args)
        {
            /*Let's create a list of type Student called Students.
             */
            List<Student> Students = new List<Student>()
            {
                 new Student {Name = "James", Age = 19, Province = "AB"  },
                 new Student { Name = "Robert", Age = 27, Province = "BC" },
                 new Student { Name = "George", Age = 18, Province = "AB" },
                 new Student { Name = "John", Age = 36, Province = "ON" },
                 new Student { Name = "Peter", Age = 11, Province = "AB" },
                 new Student {Name = "Lauren", Age = 25, Province = "SK"  },
                 new Student { Name = "Jack", Age = 35, Province = "NU" },
                 new Student { Name = "Henry", Age = 23, Province = "MB" },
                 new Student { Name = "Bob", Age = 45, Province = "AB" },
                 new Student { Name = "Wayne", Age = 11, Province = "AB" },
            };
var studentsGroupByProvinceAndAge = Students.GroupBy(Student => (Student.Province, Student.GetAgeGroup()));
            foreach (var group in studentsGroupByProvinceAndAge)
            {
                Console.WriteLine();
                Console.WriteLine("--------------------------------------------");
                Console.WriteLine("Students who are from " + group.Key.Province + " and  age group " + group.Key + ":");
                //student is each student with same age group i.e all students whose age group is same will in the same sublist
                //in the same sublist
                foreach (var student in group)
                {
                    Console.WriteLine("*" + student.Name);
                }
            }
        }
    }
}

In the above example we used composite keys for grouping that makes all students from same province and which are under the same category for the GetAgeGroup() method return are grouped together.



Citation : 
Grouping data: The GroupBy() Method. (n.d.). Retrieved September 15, 2020, from https://csharp.net-tutorials.com/linq/grouping-data-the-groupby-method/

Dotnet-Bot. (n.d.). Enumerable.GroupBy Method (System.Linq). Retrieved September 15, 2020, from https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.groupby?view=netcore-3.1