Group by query in LINQ in c#

Group by query in LINQ in c#

In this post, How to use group by query in LINQ c#. The GroupBy operator returns a group of elements from the given collection based on some key value. Each group is represented by IGrouping<TKey, TElement> object.

Example:-

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace usingcsharp
{
    class Program
    {
        static void Main(string[] args)
        {
            StudentClass sc = new StudentClass();
            sc.QueryHighScores(2, 80);

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
        public class StudentClass
        {
            protected enum GradeLevel { FirstYear = 2, SecondYear, ThirdYear, FourthYear };
            protected class Student
            {
                public string FirstName { get; set; }
                public string LastName { get; set; }
                public int ID { get; set; }
                public GradeLevel Year;
                public List<int> ExamScores;
            }

            protected static List<Student> students = new List<Student>
            {
        new Student {FirstName = "Ram", LastName = "Kumar", ID = 1,
            Year = GradeLevel.SecondYear,
            ExamScores = new List<int>{ 90, 81, 81, 80}},
        new Student {FirstName = "Amara", LastName = "Mishra", ID = 2,
            Year = GradeLevel.ThirdYear,
            ExamScores = new List<int>{ 100, 87, 91, 93}},
        new Student {FirstName = "Amartya", LastName = "Tiwari", ID = 3,
            Year = GradeLevel.FirstYear,
            ExamScores = new List<int>{ 94, 50, 80, 89}},
        new Student {FirstName = "Ambaka", LastName = "Chaurasiya", ID = 4,
            Year = GradeLevel.FourthYear,
            ExamScores = new List<int>{ 98, 89, 86, 82}},
        new Student {FirstName = "Alankrti", LastName = "Yadav", ID = 5,
            Year = GradeLevel.ThirdYear,
            ExamScores = new List<int>{ 30, 71, 91, 71}},
        new Student {FirstName = "Amaranayagan", LastName = "Gupta", ID = 6,
            Year = GradeLevel.SecondYear,
            ExamScores = new List<int>{ 92, 90, 86, 78}},
        new Student {FirstName = "Amratav", LastName = "Prasad", ID = 7,
            Year = GradeLevel.FirstYear,
            ExamScores = new List<int>{ 88, 94, 65, 91}},
        new Student {FirstName = "Arbhata", LastName = "Macho", ID = 8,
            Year = GradeLevel.FourthYear,
            ExamScores = new List<int>{ 75, 84, 20, 39}},
        new Student {FirstName = "Arghya", LastName = "Thakur", ID = 9,
            Year = GradeLevel.SecondYear,
            ExamScores = new List<int>{ 97, 92, 80, 60}},
        new Student {FirstName = "Apurva", LastName = "Verma", ID = 10,
            Year = GradeLevel.ThirdYear,
            ExamScores = new List<int>{ 68, 80, 88, 92}},
        new Student {FirstName = "Arib", LastName = "kumar", ID = 11,
            Year = GradeLevel.FirstYear,
            ExamScores = new List<int>{ 55, 92, 93, 90}},
        new Student {FirstName = "Arjuna", LastName = "Singh", ID = 12,
            Year = GradeLevel.FourthYear,
            ExamScores = new List<int>{ 90, 10, 90, 40}}
    };
           
        }
    }
}

Used in GroupByRange

protected static int GetPercentile(Student s)
            {
                double avg = s.ExamScores.Average();
                return avg > 0 ? (int)avg / 10 : 0;
            }
public void QueryHighScores(int exam, int score)
            {
                var highScores = from student in students
                                 where student.ExamScores[exam] > score
                                 select new { Name = student.FirstName, Score = student.ExamScores[exam] };

                foreach (var item in highScores)
                {
                    Console.WriteLine(string.Format("{0,-15}{1}", item.Name, item.Score));
                }
            }

Change the calling statement in the Main method to sc.GroupBySubstring()

public void GroupBySubstring()
            {
                Console.WriteLine("\r\nGroup by something other than a property of the object:");

                var queryFirstLetters =
                    from student in students
                    group student by student.LastName[0];

                foreach (var studentGroup in queryFirstLetters)
                {
                    Console.WriteLine(string.Format("Key: {0}"), studentGroup.Key);
                    // Nested foreach is required to access group items.
                    foreach (var student in studentGroup)
                    {
                        Console.WriteLine(string.Format("\t{0}, {1}"), student.LastName, student.FirstName);
                    }
                }
            }

Paste the following method into the StudentClass class. Change the calling statement in the Main method to sc.GroupBySingleProperty().

 public void GroupBySingleProperty()
            {
                Console.WriteLine("Group by a single property in an object:");

                // Variable queryLastNames is an IEnumerable<IGrouping<string,
                // DataClass.Student>>.
                var queryLastNames =
                    from student in students
                    group student by student.LastName into newGroup
                    orderby newGroup.Key
                    select newGroup;

                foreach (var nameGroup in queryLastNames)
                {
                    Console.WriteLine(string.Format("Key: {0}"), nameGroup.Key);
                    foreach (var student in nameGroup)
                    {
                        Console.WriteLine(string.Format("\t{0}, {1}"), student.LastName, student.FirstName);
                    }
                }
            }

Change the calling statement in the Main method to sc.GroupByRange().

public void GroupByRange()
            {
                Console.WriteLine("\r\nGroup by numeric range and project into a new anonymous type:");

                var queryNumericRange =
                    from student in students
                    let percentile = GetPercentile(student)
                    group new { student.FirstName, student.LastName } by percentile into percentGroup
                    orderby percentGroup.Key
                    select percentGroup;

                // Nested foreach required to iterate over groups and group items.
                foreach (var studentGroup in queryNumericRange)
                {
                    Console.WriteLine(string.Format("Key: {0 * 10}"), studentGroup.Key);
                    foreach (var item in studentGroup)
                    {
                        Console.WriteLine(string.Format("\t{0}, {1}"), item.LastName, item.FirstName);
                    }
                }
            }

Change the calling statement in the Main method to sc.GroupByBoolean()

public void GroupByBoolean()
            {
                Console.WriteLine("\r\nGroup by a Boolean into two groups with string keys");
                Console.WriteLine("\"True\" and \"False\" and project into a new anonymous type:");
                var queryGroupByAverages = from student in students
                                           group new { student.FirstName, student.LastName }
                                                by student.ExamScores.Average() > 75 into studentGroup
                                           select studentGroup;

                foreach (var studentGroup in queryGroupByAverages)
                {
                    Console.WriteLine(string.Format("Key: {0}"), studentGroup.Key);
                    foreach (var student in studentGroup)
                        Console.WriteLine(string.Format("\t{0} {1}"), student.FirstName, student.LastName);
                }
            }

Change the calling statement in the Main method to sc.GroupByCompositeKey()

 public void GroupByCompositeKey()
            {
                var queryHighScoreGroups =
                    from student in students
                    group student by new
                    {
                        FirstLetter = student.LastName[0],
                        Score = student.ExamScores[0] > 85
                    } into studentGroup
                    orderby studentGroup.Key.FirstLetter
                    select studentGroup;

                Console.WriteLine("\r\nGroup and order by a compound key:");
                foreach (var scoreGroup in queryHighScoreGroups)
                {
                    string s = scoreGroup.Key.Score == true ? "more than" : "less than";
                    Console.WriteLine(string.Format("Name starts with {0} who scored {s} 85"), scoreGroup.Key.FirstLetter);
                    foreach (var item in scoreGroup)
                    {
                        Console.WriteLine(string.Format("\t{0} {1}", item.FirstName, item.LastName));
                    }
                }
            }

OR

You can paste the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace usingcsharp
{
    class Program
    {
        static void Main(string[] args)
        {
            StudentClass sc = new StudentClass();
            sc.QueryHighScores(2, 80);

            // Keep the console window open in debug mode.
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }
        public class StudentClass
        {
            protected enum GradeLevel { FirstYear = 2, SecondYear, ThirdYear, FourthYear };
            protected class Student
            {
                public string FirstName { get; set; }
                public string LastName { get; set; }
                public int ID { get; set; }
                public GradeLevel Year;
                public List<int> ExamScores;
            }

            protected static List<Student> students = new List<Student>
            {
        new Student {FirstName = "Ram", LastName = "Kumar", ID = 1,
            Year = GradeLevel.SecondYear,
            ExamScores = new List<int>{ 90, 81, 81, 80}},
        new Student {FirstName = "Amara", LastName = "Mishra", ID = 2,
            Year = GradeLevel.ThirdYear,
            ExamScores = new List<int>{ 100, 87, 91, 93}},
        new Student {FirstName = "Amartya", LastName = "Tiwari", ID = 3,
            Year = GradeLevel.FirstYear,
            ExamScores = new List<int>{ 94, 50, 80, 89}},
        new Student {FirstName = "Ambaka", LastName = "Chaurasiya", ID = 4,
            Year = GradeLevel.FourthYear,
            ExamScores = new List<int>{ 98, 89, 86, 82}},
        new Student {FirstName = "Alankrti", LastName = "Yadav", ID = 5,
            Year = GradeLevel.ThirdYear,
            ExamScores = new List<int>{ 30, 71, 91, 71}},
        new Student {FirstName = "Amaranayagan", LastName = "Gupta", ID = 6,
            Year = GradeLevel.SecondYear,
            ExamScores = new List<int>{ 92, 90, 86, 78}},
        new Student {FirstName = "Amratav", LastName = "Prasad", ID = 7,
            Year = GradeLevel.FirstYear,
            ExamScores = new List<int>{ 88, 94, 65, 91}},
        new Student {FirstName = "Arbhata", LastName = "Macho", ID = 8,
            Year = GradeLevel.FourthYear,
            ExamScores = new List<int>{ 75, 84, 20, 39}},
        new Student {FirstName = "Arghya", LastName = "Thakur", ID = 9,
            Year = GradeLevel.SecondYear,
            ExamScores = new List<int>{ 97, 92, 80, 60}},
        new Student {FirstName = "Apurva", LastName = "Verma", ID = 10,
            Year = GradeLevel.ThirdYear,
            ExamScores = new List<int>{ 68, 80, 88, 92}},
        new Student {FirstName = "Arib", LastName = "kumar", ID = 11,
            Year = GradeLevel.FirstYear,
            ExamScores = new List<int>{ 55, 92, 93, 90}},
        new Student {FirstName = "Arjuna", LastName = "Singh", ID = 12,
            Year = GradeLevel.FourthYear,
            ExamScores = new List<int>{ 90, 10, 90, 40}}
    };
           // used in GroupByRange.
            protected static int GetPercentile(Student s)
            {
                double avg = s.ExamScores.Average();
                return avg > 0 ? (int)avg / 10 : 0;
            }
            //GroupByRange.            
            public void QueryHighScores(int exam, int score)
            {
                var highScores = from student in students
                                 where student.ExamScores[exam] > score
                                 select new { Name = student.FirstName, Score = student.ExamScores[exam] };

                foreach (var item in highScores)
                {
                    Console.WriteLine(string.Format("{0,-15}{1}", item.Name, item.Score));
                }
            }
            //GroupBySingleProperty().
            public void GroupBySingleProperty()
            {
                Console.WriteLine("Group by a single property in an object:");

                var queryLastNames =
                    from student in students
                    group student by student.LastName into newGroup
                    orderby newGroup.Key
                    select newGroup;

                foreach (var nameGroup in queryLastNames)
                {
                    Console.WriteLine(string.Format("Key: {0}"), nameGroup.Key);
                    foreach (var student in nameGroup)
                    {
                        Console.WriteLine(string.Format("\t{0}, {1}"), student.LastName, student.FirstName);
                    }
                }
            }
            //GroupBySubstring().
            public void GroupBySubstring()
            {
                Console.WriteLine("\r\nGroup by something other than a property of the object:");

                var queryFirstLetters =
                    from student in students
                    group student by student.LastName[0];

                foreach (var studentGroup in queryFirstLetters)
                {
                    Console.WriteLine(string.Format("Key: {0}"), studentGroup.Key);
                    // Nested foreach is required to access group items.
                    foreach (var student in studentGroup)
                    {
                        Console.WriteLine(string.Format("\t{0}, {1}"), student.LastName, student.FirstName);
                    }
                }
            }
            
           //GroupByBoolean()
            public void GroupByBoolean()
            {
                Console.WriteLine("\r\nGroup by a Boolean into two groups with string keys");
                Console.WriteLine("\"True\" and \"False\" and project into a new anonymous type:");
                var queryGroupByAverages = from student in students
                                           group new { student.FirstName, student.LastName }
                                                by student.ExamScores.Average() > 76 into studentGroup
                                           select studentGroup;

                foreach (var studentGroup in queryGroupByAverages)
                {
                    Console.WriteLine(string.Format("Key: {0}"), studentGroup.Key);
                    foreach (var student in studentGroup)
                        Console.WriteLine(string.Format("\t{0} {1}"), student.FirstName, student.LastName);
                }
            }
            //GroupByCompositeKey().
            public void GroupByCompositeKey()
            {
                var queryHighScoreGroups =
                    from student in students
                    group student by new
                    {
                        FirstLetter = student.LastName[0],
                        Score = student.ExamScores[0] > 86
                    } into studentGroup
                    orderby studentGroup.Key.FirstLetter
                    select studentGroup;

                Console.WriteLine("\r\nGroup and order by a compound key:");
                foreach (var scoreGroup in queryHighScoreGroups)
                {
                    string s = scoreGroup.Key.Score == true ? "more than" : "less than";
                    Console.WriteLine(string.Format("Name starts with {0} who scored {s} 86"), scoreGroup.Key.FirstLetter);
                    foreach (var item in scoreGroup)
                    {
                        Console.WriteLine(string.Format("\t{0} {1}", item.FirstName, item.LastName));
                    }
                }
            }
//GroupByRange().
            public void GroupByRange()
            {
                Console.WriteLine("\r\nGroup by numeric range and project into a new anonymous type:");

                var queryNumericRange =
                    from student in students
                    let percentile = GetPercentile(student)
                    group new { student.FirstName, student.LastName } by percentile into percentGroup
                    orderby percentGroup.Key
                    select percentGroup;

              
                foreach (var studentGroup in queryNumericRange)
                {
                    Console.WriteLine(string.Format("Key: {0 * 10}"), studentGroup.Key);
                    foreach (var item in studentGroup)
                    {
                        Console.WriteLine(string.Format("\t{0}, {1}"), item.LastName, item.FirstName);
                    }
                }
            }
        }
    }
}

2021-10-03