Partitioning Operators in Linq

by Sachin Singh


Posted on Thursday, 04 February 2021

Tags: Partitioning operator in LINQ Take(), Skip(), TakeWhile(), SkipWhile() operators in Linq

How to think
How to think when working with LINQ

The General meaning of partition is separating something into two parts, similarly, In LINQ, partition operators are used to divide a list or collection items into two parts and return one of them, the partioning of collection is decided by the condition, it accepts as parameter.

There are four types of partition operators available in LINQ, they are :
    • TAKE
    • TAKEWHILE
    • SKIP
    • SKIPWHILE

The partition operators are used to partion a collection of items or List of items into two parts based on a specific condtion and then it returns one of the part.

The following diagram shows more detailed information about partition operators in LINQ.

Linq wrt different datasource
Partition Operators in Linq

Now let's discuss each of these operators with some examples

Take Operator

Take() standard query operator simply returns the first n items from a collection, the collection literally can be anything like collection of integers, collection of complex objects, collection of strings etc.

We have already learnt that syntax for querying any type of data source is same as long as we use LINQ , it is the LINQ provider which converts LINQ query to data source specific syntaxes for example we don't query a database directly, we just query collection of in-memory objects and then LINQ provider translates them into corresponding T-SQL statements.

Example Return first 5 strings from the collection shown below.


  string[] countries = {"India","Australia","Pakistan","Japan","Nepal","England","America","Afganistan","Sri Lanka"};
  var TopFiveCountries= countries.Take(5);

In the above example we are able to apply Take() extension method because all collections in C# are inherited from IEnumerableand all LINQ standard query operators are extension methods on IEnumerabletype. As Array is inherited from IEnumerablewe are able to use Take() operator on Array Type.

Example : Return first 5 Employees from the collection of Employees.


     public class Program
     {
        public static void Main()
        {
            List<Employee> emps = new List<Employee>()
            {
              new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritalStatus ="UnMarried"},
              new Employee(){Id=1,Name="Arjun",Phone=345678903, Gender="Male", MaritalStatus ="UnMarried"},
              new Employee(){Id=1,Name="Vikash",Phone=345678904, Gender="Male", MaritalStatus ="UnMarried"},
              new Employee(){Id=1,Name="Nivi",Phone=345678905, Gender="Female", MaritalStatus ="UnMarried"},
              new Employee(){Id=1,Name="Abhijeet",Phone=345678906, Gender="Male", MaritalStatus ="UnMarried"},
              new Employee(){Id=1,Name="Niraj",Phone=345678907, Gender="Male", MaritalStatus ="UnMarried"},
              new Employee(){Id=1,Name="Diwakar",Phone=345678908, Gender="Male", MaritalStatus ="Married"}
            };
           
            var res = emps.Take(5);

            foreach (var emp in res)
            {
                Console.WriteLine(emp.Name+" "+ emp.Gender);
            }
            Console.ReadLine();
        }


        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int Phone { get; set; }
            public string Gender { get; set; }
            public string MaritalStatus { get; set; }
        }


Again ,In the above example we were able to apply Take() extension method because all collections in C# are inherited from IEnumerable and all LINQ standard query operators are extension methods on IEnumerabletype. As List are inherited from IEnumerablewe can use Take() operator on any List type.

TakeWhile() operator

TakeWhile() operator simply returns items from a collection until the specified condition becomes true , TakeWhile() operator accepts a Func generic delegate , and if you could recall from previous article then it should be known to you that a delegate can point to any method of same signature ,and if you want to declare an inline delegate then you can either use anonymous method or lambda expressions. Let's understand it with some example.

Example. Return all countries until you find a country of length less than or equals to 10.


       public static void Main()
        {      
            string[] countries = { "India", "Australia", "Pakistan", "Japan", "Nepal" };
            var res = countries.TakeWhile(condition);
            foreach (var country in res)
            {
                Console.WriteLine(country);
            }
            Console.ReadLine();

        }

        public static bool condition(string str)
        {
            if (str.Length <= 5)
            {
                return true;
            }
            return false;
        }

In the following example, TakeWhile() method returns a new collection of strings containing all elements from the source collection until it finds a string of length less than or equals to 10. The same code can be rewritten with the help of lambda expression as shown below.


    public static void Main()
     {
            string[] countries = { "India", "Australia", "Pakistan", "Japan", "Nepal" };
            var res = countries.TakeWhile(x=>x<=10);
            foreach (var country in res)
            {
                Console.WriteLine(country);
            }
            Console.ReadLine();
        }      

Skip Operator

Skip() extension method simply skips the first n items from a collection and returns rest of the items(collection). Here the collection literally can be anything like collection of integers, collection of complex objects, collection of strings etc.

Example 1. Return all strings after first 5 strings from the collection.


   string[] countries = {"India","Australia","Pakistan","Japan","Nepal","England","America","Afganistan","Sri Lanka"};
  var TopFiveCountries= countries.skip(5);

In the above example we are able to apply Take() extension method because all collections in C# are inherited from IEnumerableand all LINQ standard query operators are extension methods on IEnumerabletype. As Array are inherited from IEnumerablewe could use Skip() operator easily.

Example: Return all employees after first 5 Employee from the collection.


     public class Program
     {
        public static void Main()
        {
            List<Employee> emps = new List<Employee>()
            {
              new Employee() {Id=1,Name="Sachin",Phone=345678901,Gender="Male", MaritialStatus ="UnMarried"},
              new Employee(){Id=1,Name="Arjun",Phone=345678903, Gender="Male", MaritialStatus ="UnMarried"},
              new Employee(){Id=1,Name="Vikash",Phone=345678904, Gender="Male", MaritialStatus ="UnMarried"},
              new Employee(){Id=1,Name="Nivi",Phone=345678905, Gender="Female", MaritialStatus ="UnMarried"},
              new Employee(){Id=1,Name="Abhijeet",Phone=345678906, Gender="Male", MaritialStatus ="UnMarried"},
              new Employee(){Id=1,Name="Niraj",Phone=345678907, Gender="Male", MaritialStatus ="UnMarried"},
              new Employee(){Id=1,Name="Diwakar",Phone=345678908, Gender="Male", MaritialStatus ="Married"}
            };
           
            var res = emps.Skip(5);

            foreach (var emp in res)
            {
                Console.WriteLine(emp.Name+" "+ emp.Gender);
            }
            Console.ReadLine();
        }


        public class Employee
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public int Phone { get; set; }
            public string Gender { get; set; }
            public string MaritialStatus { get; set; }
        }


In the above example we are able to apply Take() extension method because all collections in C# are inherited from IEnumerableand all LINQ standard query operators are extension methods on IEnumerabletype. As List are inherited from IEnumerablewe could use Take() operator here.

SkipWhile() operator

Similar to TakeWhile() operator ,SkipWhile () operator skips items from a collection until the specified condition becomes true and then returns the remaining items from the collection. SkipWhile() operator accepts a Func generic delegate , and we know that a delegate can point to any method of same signature ,and if we want to declare an inline delegate then we could either use anonymous method or lambda expressions. Let's understand it with some example.

Example: Return all countries after you find a country of length less than or equals to 7.


    public static void Main()
    {
            string[] countries = { "India", "Australia", "Pakistan", "Japan", "Nepal" };
            var res = countries.SkipWhile(condition);
            foreach (var country in res)
            {
                Console.WriteLine(country);
            }
            Console.ReadLine();

        }

        public static bool condition(string str)
        {
            if (str.Length <= 7)
            {
                return true;
            }
            return false;
        }

The above code can be rewritten with the help of lambda expressions as shown below.


    public static void Main()
    {
            string[] countries = { "India", "Australia", "Pakistan", "Japan", "Nepal" };
            var res = countries.SkipWhile(x=>x.Length<=7);
            foreach (var country in res)
            {
                Console.WriteLine(country);
            }
            Console.ReadLine();
        }       

In the following example, TakeWhile() method returns a new collection that includes all the elements after it finds a string whose length is less than or equals to 7 characters. We will discuss each of these operators in details in later chapters.