C # Wonderful functions-6. Five sequence aggregation operations (Sum, Average, Min, Max, Aggregate)

Source: Internet
Author: User

Today, we will focus on five aggregate operations for sequences. Most of the time when we operate on sequences, we want to execute some summary based on these sequences and then calculate the results.


EnumerableThis can be done by using the static class's LINQ extension method. Just like most of the previously-used methods for extension of LINQ, these are based onIEnumerable <TSource>Sequence operations.

SUM ()-calculate the SUM of the entire sequence

It has two forms:

  • SUM ()

    • Calculates the total value of the entire sequence.
    • The source type must be one of the following:Int, long, double, decimal,SingleOr empty variants of these types (int ?, Long ?, Double ?...) .
  • Sum (Func <TSource,X>Projection)
    • Calculates the sum of projection values of a sequence.
    • From MSDN, we know that X must be one of the following types:Int, long, double, decimal,SingleOr empty variants of these types (int ?, Long ?, Double ?...) .


Pay attention to several things here.


First, although C # supports many types,SUM ()Method-non-projection-only supportedInt, long, double, decimal,Single.


1: // correct

2: double [] data = {3.14, 2.72, 1.99, 2.32 };

3: var result = data. Sum ();


5: // not supported

6: short [] Using Data = {1, 2, 5, 7 };


8: // An error occurred while editing

9: var shortResult = partition data. Sum ();

Note that you can perform the preceding operations to allow Null mutations that can be Null. As we have discussed before, it can be a tricky thing to use a null type,SUM ()We don't have to worry about it, because all null values are excluded in sum:


Var data = new List <int?> {1, 3, 9, 13, null, 7, 12, null };
Var result = data. Sum ();

Second, the projection form is an interesting and useful method:

To illustrate this, let's assume a simple POCO Employee:



Public sealed class Employee


Public string Name {get; set ;}

Public double Salary {get; set ;}

Public short Dependents {get; set ;}



Var employees = new List <Employee>


New Employee {Name = "Bob", Salary = 35000.00, Dependents = 0 },

New Employee {Name = "Sherry", Salary = 75250.00, Dependents = 1 },

New Employee {Name = "Kathy", Salary = 32000.50, Dependents = 0 },

New Employee {Name = "Joe", Salary = 17500.00, Dependents = 2 },



Then we can use the projection method to get the total Salary value:

var totalSalary = employees.Sum(e => e.Salary);
Although the projection form appears to be restricted to the above types (Int, long, single, double, decimal), But if we use lambda expressions or anonymous expressions, the projection form will allow shorter types:
employees.Sum(e => e.Dependents);

employees.Sum(delegate(Employee e) { return e.Dependents; });
This is because the result of lambda expressions and anonymous delegation can automatically expand the small value type (such as short) to int.
Average ()-returns the Average value of the sequence

Average ()Method, just likeSUM(), Except that the sum is divided by the number of actually involved projects. What does it mean? Remember, SUM () Does not include null values. Average() YesSet all non-NullCalculate the average value. For example:



Var intList = new int? [] {10, 20, 30, null };

// Return 20

Console. WriteLine (intList. Average ());

MIN ()-returns the smallest Sequence Value

MIN ()The extension method is used to study the sequence and return the minimum value from it:

  • Min ()

    • Find the smallest value in the sequence.
    • Throw an exception.IComparableOrIComparable <T>.
    • Throw an exception. If the sequence is empty, the source type is the value type.
    • If the sequence is null and X is the reference type or Nullable value typeReturnNull.
  • Min (Func <TSource,X>Projection)
    • Returns the minimum value of a generic sequence.
    • If the TSource type is implementedIComparable <T>, This method uses this implementation to compare values. Otherwise, if the TSource type is implementedIComparable.
    • Throw an exception. If the sequence is null, X indicates the value type.
    • If TSource is of the reference type and the source sequence is null or contains only null values, this function returns null.


MIN ()Supports almost any type, as long as this type is implementedIComparableOrIComparable<T>. Therefore, it is an unlimited value type.Can be used for any comparative object (including the image value type)DateTime, TimeSpan):



Var shortList = new short [] {1, 3, 7, 9,-9, 33 };

// Return-9

Var smallest = shortList. Min ();

// Find the minimum value based on the number of family members

Var minDependents = employees. Min (e => e. Dependents );

In addition,MIN ()Do not use generic constraints to restrict the type parameters that support the IComparable interface. Instead, it throws a running exception to respond to a non-empty sequence that is not implemented in its object.IComparable.
Therefore, if we use the previously defined Employee class, the first call below will returnNull(The sequence is empty), the second call will throw (not empty, but does not containIComparableObject Sequence ).

var result1 = Enumerable.Empty<Employee>().Min();

var result2 = employees.Min();
Finally, note that for the value type, if the sequence is null, an exception is thrown, so the following two will throw an exception:

var result3 = Enumerable.Empty<int>().Min();

var result4 = Enumerable.Empty<Employee>().Min(e => e.Dependents);
MAX ()-returns the largest Sequence Value.

MAX ()MIN ()But it returns the maximum value instead of the minimum value. Therefore, we can use the maximum values in these sequences or predict the maximum values from a sequence:

/// Return 33
VAR biggestShort = shortList. Max ();

// Return 75250.0
VAR highestSalary = employees. Max (E => e. Salary );

For more information, see Min ().

Aggregate ()-custom accumulators of Sequences


There are three formsAggregate ():

  • Aggregate (Func <TSource, TSource, TSource>Function)

    • It is applicable to a function that accepts the value of an accumulator and the next value and returns the result.
    • The value and sequence type are the same.
    • The seed value is the first value in the sequence.
  • Aggregate (TAccumulateSeed, Func <TAccumulate, TSource, TAccumulate>Function)
    • Apply a function in the sequence, the iterator value, and the next item, and return a result.
    • The values and sequence types can be different or the same.
    • You must provide a seed value for initialization and use the specified seed value as the initial value of the accumulators.
  • Aggregate (TAccumulateSeed, Func <TAccumulate, TSource, TAccumulate>Function, Func <TAccumulate, TResult>ResultProjection)
    • Use the specified seed value as the initial value of the accumulators and select the result value using the specified function.

This may seem quite complicated. Just remember that "the working principle of this method is to call func once for every element in the source. Each time you call func, the elements and aggregate values in the sequence are passed (as the first parameter of func ). Replace the previous aggregate value with the result of func ."


For example, if we want to multiply all numbers in a sequence:


Var numbers = new int [] {1, 3, 9, 2 };

// Use the current total value multiplied by the next value to obtain the new total value.
Var product = numbers. Aggregate (total, next) => total * next );

The final value is: 1X3X9X2 = 54.



Next let's take a look at how to use more complex aggregate computing. We may want to get this result: divide the salary of each employee by the total household population (including his own), and then add these values:


var weirdCalculation = employees.Aggregate(0.0, 

(result, next) => result + next.Salary / (next.Dependents + 1));
According to the above definition of Empolyee, the result is 110458.8333. For ease of understanding, see the following Excel table:

So you can see that we can perform very complex aggregate computing. The key is to remember that the function you provide is left to the next "element ", and apply it to the running "total value ".



Four simple ones and one may be a little complicated. This group of functions is quite powerful! These methods can easily aggregate sequences so that you do not need to perform loops or self-calculation. They are fast and easy to use, they are easy to read, and they have been fully tested. Please enjoy it!

For more exciting articles, read ASP. NET (Alex Song) This document is translated fromC #/. NET Little Wonders: Five Easy Sequence Aggregators
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.