Home Programming LINQ to Objects

LINQ to Objects

0
1592
9 min read

Without LINQ, we would have to go through the values one-by-one and then find the required details. However, using LINQ we can directly query collections and filter the required values without using any looping. LINQ provides powerful filtering, ordering, and grouping capabilities that requires minimum coding. For example, if we want to find out the types stored in an assembly and then filter the required details, we can use LINQ to query the assembly details using System.Reflection classes. The System.Reflection namespace contains types that retrieve information about assemblies, modules, members, parameters, and other entities as collections are managed code, by examining their metadata. Also, files under a directory are a collection of objects that can be queried using LINQ. We shall see some of the examples for querying some collections.

Array of Integers

The following example shows an integer array that contains a set of integers. We can apply the LINQ queries on the array to fetch the required values.

Learn Programming & Development with a Packt Subscription
    int[] integers = { 1, 6, 2, 27, 10, 33, 12, 8, 14, 5 };
       IEnumerable<int> twoDigits =
       from numbers in integers
       where numbers >= 10
       select numbers;
       Console.WriteLine("Integers > 10:");
       foreach (var number in twoDigits)
       {
          Console.WriteLine(number);
       }

The integers variable contains an array of integers with different values. The variable twoDigits, which is of type IEnumerable, holds the query. To get the actual result, the query has to be executed.

The actual query execution happens when the query variable is iterated through the foreach loop by calling GetEnumerator() to enumerate the result. Any variable of type IEnumerable<T>, can be enumerated using the foreach construct. Types that support IEnumerable<T> or a derived interface such as the generic IQueryable<T>, are called queryable types. All collections such as list, dictionary and other classes are queryable. There are some non-generic IEnumerable collections like ArrayList that can also be queried using LINQ. For that, we have to explicitly declare the type of the range variable to the specific type of the objects in the collection, as it is explained in the examples later in this article.

The twoDigits variable will hold the query to fetch the values that are greater than or equal to 10. This is used for fetching the numbers one-by-one from the array. The foreach loop will execute the query and then loop through the values retrieved from the integer array, and write it to the console. This is an easy way of getting the required values from the collection.

If we want only the first four values from a collection, we can apply the Take() query operator on the collection object. Following is an example which takes the  first four integers from the collection. The four integers in the resultant collection are displayed using the foreach method.

   IEnumerable<int> firstFourNumbers = integers.Take(4);
   Console.WriteLine("First 4 numbers:");
   foreach (var num in firstFourNumbers)
   {
      Console.WriteLine(num);
   }

The opposite of Take() operator is Skip() operator, which is used to skip the number of items in the collection and retrieve the rest. The following example skips the first four items in the list and retrieves the remaining.

   IEnumerable<int> skipFirstFourNumbers = integers.Skip(4);
   Console.WriteLine("Skip first 4 numbers:");
   foreach (var num in skipFirstFourNumbers)
   {
      Console.WriteLine(num);
   }

This example shows the way to take or skip the specified number of items from the collection. So what if we want to skip or take the items until we find a match in the list? We have operators to get this. They are TakeWhile() and SkipWhile().

For example, the following code shows how to get the list of numbers from the integers collection until 50 is found. TakeWhile() uses an expression to include the elements in the collection as long as the condition is true and it ignores the other elements in the list. This expression represents the condition to test the elements in the collection for the match.

   int[] integers = { 1, 9, 5, 3, 7, 2, 11, 23, 50, 41, 6, 8 };
   IEnmerable<int> takeWhileNumber = integers.TakeWhile(num =>
      num.CompareTo(50) != 0);
   Console.WriteLine("Take while number equals 50");
   foreach (int num in takeWhileNumber)
      {
         Console.WriteLine(num.ToString());
      }

Similarly, we can skip the items in the collection using SkipWhile(). It uses an expression to bypass the elements in the collection as long as the condition is true. This expression is used to evaluate the condition for each element in the list. The output of the expression is boolean. If the expression returns false, the remaining elements in the collections are returned and the expression will not be executed for the other elements. The first occurrence of the return value as false will stop the expression for the other elements and returns the remaining elements. These operators will provide better results if used against ordered lists as the expression is ignored for the other elements once the first match is found.

   IEnumerable<int> skipWhileNumber = integers.SkipWhile(num =>
      num.CompareTo(50) != 0);
   Console.WriteLine("Skip while number equals 50");
   foreach (int num in skipWhileNumber)
   {
      Console.WriteLine(num.ToString());
   }

Collection of Objects

In this section we will see how we can query a custom built objects collection. Let us take the Icecream object, and build the collection, then we can query the collection. This Icecream class in the following code contains different properties such as Name, Ingredients, TotalFat, and Cholesterol.

    public class Icecream
    {
        public string Name { get; set; }
        public string Ingredients { get; set; }
        public string TotalFat { get; set; }
        public string Cholesterol { get; set; }
        public string TotalCarbohydrates { get; set; }
        public string Protein { get; set; }
        public double Price { get; set; }

    }

Now build the Icecreams list collection using the class defined perviously.

    List<Icecream> icecreamsList = new List<Icecream>
        {
            new Icecream {Name=”Chocolate Fudge Icecream”, Ingredients=”cream,
                milk, mono and diglycerides…”, Cholesterol=”50mg”,
                Protein=”4g”, TotalCarbohydrates=”35g”, TotalFat=”20g”,
                Price=10.5
        },
        new Icecream {Name=”Vanilla Icecream”, Ingredients=”vanilla extract,
            guar gum, cream…”, Cholesterol=”65mg”, Protein=”4g”,
            TotalCarbohydrates=”26g”, TotalFat=”16g”, Price=9.80 },
            new Icecream {Name=”Banana Split Icecream”, Ingredients=”Banana, guar
            gum, cream…”, Cholesterol=”58mg”, Protein=”6g”,
            TotalCarbohydrates=”24g”, TotalFat=”13g”, Price=7.5 }
        };

We have icecreamsList collection which contains three objects with values of the Icecream type. Now let us say we have to retrieve all the ice-creams that cost less. We can use a looping method, where we have to look at the price value of each object in the list one-by-one and then retrieve the objects that have less value for the Price property. Using LINQ, we can avoid looping through all the objects and its properties to find the required ones. We can use LINQ queries to find this out easily. Following is a query that fetches the ice-creams with low prices from the collection. The query uses the where condition, to do this. This is similar to relational database queries. The query gets executed when the variable of type IEnumerable is enumerated when referred to in the foreach loop.

    List<Icecream> Icecreams = CreateIcecreamsList();
    IEnumerable<Icecream> IcecreamsWithLessPrice =
    from ice in Icecreams
    where ice.Price < 10
    select ice;
    Console.WriteLine(“Ice Creams with price less than 10:”);
    foreach (Icecream ice in IcecreamsWithLessPrice)
    {
        Console.WriteLine(“{0} is {1}”, ice.Name, ice.Price);

    }

As we used List<Icecream> objects, we can also use ArrayList to hold the objects, and a LINQ query can be used to retrieve the specific objects from the collection according to our need. For example, following is the code to add the same Icecreams objects to the ArrayList, as we did in the previous example.

    ArrayList arrListIcecreams = new ArrayList();
    arrListIcecreams.Add( new Icecream {Name=”Chocolate Fudge Icecream”,
        Ingredients=”cream, milk, mono and diglycerides…”,
        Cholesterol=”50mg”, Protein=”4g”, TotalCarbohydrates=”35g”,
        TotalFat=”20g”, Price=10.5 });
    arrListIcecreams.Add( new Icecream {Name=”Vanilla Icecream”,
        Ingredients=”vanilla extract, guar gum, cream…”,
        Cholesterol=”65mg”, Protein=”4g”, TotalCarbohydrates=”26g”,
        TotalFat=”16g”, Price=9.80 });
    arrListIcecreams.Add( new Icecream {Name=”Banana Split Icecream”,
        Ingredients=”Banana, guar gum, cream…”, Cholesterol=”58mg”,
        Protein=”6g”, TotalCarbohydrates=”24g”, TotalFat=”13g”, Price=7.5
    });

Following is the query to fetch low priced ice-creams from the list.

    var queryIcecreanList = from Icecream icecream in arrListIcecreams
    where icecream.Price < 10
    select icecream;

Use the foreach loop, shown as follows, to display the price of the objects retrieved using the above query.

    foreach (Icecream ice in queryIcecreanList)
    Console.WriteLine(“Icecream Price : ” + ice.Price);


NO COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here