As per the Microsoft
Language Integrated Query is a Microsoft .NET Framework component that adds native data querying capabilities to .NET languages, originally released as a major part of .NET Framework 3.5 in 2007.
LINQ provides many Operators like Select, Where, Count, and many more out of the box. In this article, I will discuss the Aggregate operator, which is multi-purpose. This operator can be used in a lot of places. Let’s understand with examples.
Example 1- Join array of string to CSV
You can use the String join method
void Main()
{
var input = new[] { "John","Bill","Doe","Alex" };
var csv=string.Join(",",input);
Console.WriteLine(csv);
}
Let’s re-write the same code using the Aggregate operator
void Main()
{
var input = new[] { "John","Bill","Doe","Alex" };
var csv=JoinString(input,",");
Console.WriteLine(csv);
}
public string JoinString(string[] inputs, string seprator = ",")
{
return inputs.Aggregate((first, current) => first + seprator + current);
}
Example 2- Sum the given array
void Main()
{
var input = new[] { 1,2,3,4};
var sum=SumWIthAggregate(input);
Console.WriteLine(sum);
}
public int SumWIthAggregate(int[] arr)
{
return arr.Aggregate((first, current) => first + current);
}
Aggregate operator usage with a seed value
Let’s suppose you want to pass the sum initial value that the initial value must add in the array; then, you can use the overloaded version of the Aggregate operator as shown below. The following code example demonstrates how to use Aggregate to apply an accumulator function and a result selector.
Example 1
void Main()
{
var input = new[] { 1,2,3,4};
var sum=SumWithInitialValue(2,input);
Console.WriteLine(sum);
}
public int SumWithInitialValue(int intialValue,int[] arr)
{
return arr.Aggregate(intialValue, (first, current) => first + current);
}
As you can see in the above example that I am passing the seed value as 2
Example 2
Let’s assume you want to find whether a string in the array is longer than the given string.
void Main(){
var stringToCompare="banana";
string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" };
// Determine whether any string in the array is longer than "banana".
string longestName =
fruits.Aggregate(stringToCompare,
(longest, next) =>
next.Length > longest.Length ? next : longest,
// Return the final result as an upper case string.
fruit => fruit.ToUpper());
Console.WriteLine(
"The fruit with the longest name is {0}.",
longestName);
}
You can see in the above example that I am comparing the length of seed value with every element of the array to find the max.
Example 3 - Create a pipeline
This is my favourite example of Aggregate. By using the Aggregate operator, you can create a very advanced search functionality. Let me show you an example.
public static class MyExtensions
{
public static IEnumerable<T> Pipeline<T>(this IEnumerable<T> query, bool include, params Func<IEnumerable<T>, IEnumerable<T>>[] pipeline)
{
return include
? pipeline.Aggregate(query,
(current, func) => func.Invoke(current))
: query;
}
}
How to use
void Main()
{
var products = new List<Product>()
{
new Product{Id=1,Name="Apple",Price=2.1},
new Product{Id=2,Name="Orange",Price=2},
new Product{Id=3,Name="Mango",Price=4},
new Product{Id=4,Name="Kiwi",Price=10},
new Product{Id=4,Name="Appricoat",Price=1}
};
// Return all products whose name start with "A" and there price values is less than 4
// Each pipeline filter pass the data to next one
var results = products.
Pipeline(true, (x) => x.Where(p => p.Name.StartsWith("A")).
Pipeline(true, (x) => x.Where(cs => cs.Price < 4)));
Console.WriteLine(results);
}