Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

LINQ Extension Methods

0.00/5 (No votes)
16 Jun 2008 1  
Calling LINQ Extension Methods on Generic Collections

Introduction

In this quick and simple article, we go over some of the extension methods defined in the System.Linq namespace, introduced in version 3.5 of the .NET Framework.

Background

Iterating through collections and analyzing the data contained in them is a commonly performed task in programming. The LINQ extension methods are one of the tools available to .NET developers in version 3.5 to expedite and simplify working with collections.

Using the Code

We can start by assuming that somewhere in the code, a System.Collections.Generic dictionary has been populated with data. Each key in the dictionary is a user name string, and each value is a generic list object that holds integer values pertaining to each user:

Dictionary<string, List<int>> Users = new Dictionary<string, List<int>>();
Users.Add("Joe, Smith", new List<int>() { 20, 18, 12});
Users.Add("Jane, Doe", new List<int>() { 20, 20, 20, 18 });
Users.Add("Tom, Beck", new List<int>() { 14, 15, 20, 17 });        

We may be interested in extracting all the user names from the generic dictionary into a single generic list, as follows:

List<string> lstUserNames = Users.Keys.ToList<string>();

Similarly, we can extract all the user data lists from the generic dictionary into a single generic list where each element is its own generic list:

List<List<int>> lstUserData = Users.Values.ToList<List<int>>();

We may have a requirement to sum up all the data elements that make up each user data list. For this, we can call the Aggregate extension method, which can be applied to an object that implements IEnumerable<TSource> and accepts a delegate as an argument, as follows:

List<int> lstSums = new List<int>();
foreach (List<int> l in lstUserData)
{
    lstSums.Add(l.Aggregate((sum, elmnt) => sum + elmnt));
}

In the above for loop, we iterate through each element of the lstUserData generic list, where each element happens to be its own generic list of integer values. Note the Lambda expression used to represent the delegate passed in as an argument.

The delegate for the Aggregate extension method accepts two integer arguments and returns an integer value representing the sum of both input parameters. The Aggregate extension method loops through each element of the list and performs the operation returned by the delegate passed in.

Alternatively, and instead of using lambda expressions, we could have used anonymous methods to write an inline delegate:

foreach (List<int> l in lstUserData)
{
    lstSums.Add(l.Aggregate(delegate(int sum, int elmnt) { return sum + elmnt;} ));
}

Other extension methods can be called on the above lists. For example, we can call one for calculating the average of values in a list, checking whether a certain boolean condition is met by every element in a list and checking whether a certain condition is met by any of the elements in a list:

List<double> lstAvges = new List<double>();
List<bool> lstAllBool = new List<bool>();
List<bool> lstAnyBool = new List<bool>(); 
    
foreach (List<int> l in lstUserData)
{
    lstAvges.Add(l.Average());
    lstAllBool.Add(l.All(elmnt => elmnt >= 14));
    lstAnyBool.Add(l.Any(elmnt => elmnt == 20));
}

The All extension method iterates through a list and returns true if all elements meet a specified boolean condition. In the example above, a true is returned if all elements in the list are greater than or equal to 14.

The Any extension method iterates through a list and returns true if any of the elements meet a specified boolean condition. In the example above, a true is returned if any of the elements in the list have a value of 20.

The above code can alternatively be written using anonymous methods when defining the input delegates rather than the simpler lambda expressions:

foreach (List<int> l in lstUserData)
{
    lstAvges.Add(l.Average());
    lstAllBool.Add(l.All(delegate(int elmnt) { return elmnt >= 14; }));
    lstAnyBool.Add(l.Any(delegate(int elmnt) { return elmnt == 20; }));
}

The lstSums generic list, in which each element is a sum of all the elements in each of the user data lists in the dictionary, can be used to call the OrderBy extension method on it, which sorts its elements in an ascending order:

var sums = lstSums.OrderBy(elmnt => elmnt);

The resulting sorted list can then be bound to a GridView control and displayed on a form:

GridView1.DataSource = sums;
GridView1.DataBind();
GridView1.HeaderRow.Visible = false;

Points of Interest

Lambda expressions simplify the definition of delegates when passed in as arguments, as shown in the code above. Additionally, the LINQ extension methods, such as the ones called in this article, offer quick and easy ways for manipulating data in collections, and returning subsets of these collections based on simply defined conditions.

History

  • 16th June, 2008: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here