C#Aggregate accumulator

C#Aggregate accumulator

What is an accumulator? How to use the accumulator? Don't worry, a new technology is basically born to meet certain needs. Starting from the needs, it is easier to understand the characteristics of this function.

最后更新 4/20/2022 7:11 AM
遇水寒
预计阅读 5 分钟
分类
.NET
标签
.NET C# Aggregate

1. demand

What is an accumulator? How to use the accumulator? Don't worry, a new technology is basically born to meet certain needs. Starting from the needs, it is easier to understand the characteristics of this function.

For ease of understanding, suppose there is a one-dimensional array of int, storing 5 numbers, find the sum (-1) of the first value (-1) plus the second value (0), add the calculated value (-1) to the third number (3) of the array, add (2) again, and add the value to the fourth number (5) of the array again... By analogy, the result is: int result = -1 + 0 + 3 + 5 + 8;

int[] numbers={-1, 0, 3, 5,8};

1.1 basic needs

//V1.0版本
static void Main(string[] args)
{
    int[] numbers = { -1, 0, 3, 5, 8 };
    int result = numbers[0];
    for (int i = 1; i < numbers.Length; i++)
    {
        result = result + numbers[i];
    }
    Console.WriteLine(result);//输出15
    Console.ReadKey();
}

1.2 Encapsulation algorithm part

Extract the algorithm in the middle so that you can enter other int arrays of different lengths:

//V1.1 版本
static void Main(string[] args)
{
    int[] numbers = { -1, 0, 3, 5, 8 };
    var result = Aggregate(numbers);
    Console.WriteLine(result);
    Console.ReadKey();
}

static int Aggregate(int[] array)
{
    int result = array[0];
    for (int i = 1; i < array.Length; i++)
    {
        result = result + array[i];
    }
    return result;
}

1.3 Not just implementing addition-algorithmic substitution

The accumulator needs to be more than just adding, for example:

int result = -1 * 0 * 3 * 5 * 8;

int result = -1 - 0 - 3 - 5 - 8;
//V1.2 版本,实现算法替换
//需了解委托,Lambda相关知识
static void Main(string[] args)
{
    int[] numbers = { -1, 0, 3, 5, 8 };
    var result = Aggregate(numbers,(result,next)=>result * next);//实现乘法
    //var result = Aggregate(numbers,(result,next)=>result - next);//实现减法
    Console.WriteLine(result);
    Console.ReadKey();
}

static int Aggregate(int[] array,Func<int,int,int> func)
{
    int result = array[0];
    for (int i = 1; i < array.Length; i++)
    {
        result = func(result, array[i]);
    }
    return result;
}

1.4 Not just int types-generics

目前该算法int Aggregate(int[] array,Func<int,int,int> func)只支持 int 类型,现在要扩展到任意类型–泛型。

//V1.3 版本,实现泛型
//需了解泛型,IEnumerator接口相关知识
static void Main(string[] args)
{
    int[] numbers = { -1, 0, 3, 5, 8 };
    var result = Aggregate(numbers, (result, next) => result + next);
    Console.WriteLine(result);
    Console.ReadKey();
}

static TSource Aggregate<TSource>(IEnumerable<TSource> source,Func<TSource, TSource, TSource> func)
{
    using (IEnumerator<TSource> e = source.GetEnumerator())
    {
        if (!e.MoveNext())
        {
            throw new ArgumentException();
        }

        TSource result = e.Current;
        while (e.MoveNext())
        {
            result = func(result, e.Current);
        }

        return result;
    }
}

1.5 Implementation method becomes expansion method

Add extension methods directly to classes that implement the IEnumerator interface. At this point, the functions implemented by this Aggregate are similar to the accumulator provided by the official website.

//V1.4 版本,扩展方法
class Program
{
    static void Main(string[] args)
    {
        int[] numbers = { -1, 0, 3, 5, 8 };
        var result = numbers.Aggregate((result, next) => result + next);
        Console.WriteLine(result);
        Console.ReadKey();
    }
}

public static class Helper
{
    public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
    {
        using (IEnumerator<TSource> e = source.GetEnumerator())
        {
            if (!e.MoveNext())
            {
                throw new ArgumentException("需要至少两个元素");
            }

            TSource result = e.Current;
            while (e.MoveNext())
            {
                result = func(result, e.Current);
            }

            return result;
        }
    }
}

2. APIs provided by Microsoft

Under the System.Linq namespace, you provide:

1. public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func);

2. public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func);

3. public static TResult Aggregate<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector);

The first interface has the same function as my example above. The other two functions will be explained later (if you have time).

3. from shallow to deep

如果是初学者,可能大脑第一反应还是觉得这个Aggregate只能加减乘除,如果这样想,说明其实还是理解得不够深刻,现在来深度剖析该方法的传参:func

As shown in the figure below, the accumulator traverses each element. Except for the first time, it directly takes the first and second elements to perform func operation. Starting from the third one, it takes the result of the previous calculation as the first input parameter of func. The second input parameter is the next element of the array until the end of the traversal, and returns a final result value.

Practical use: When a table in the database references foreign keys of multiple tables, when you need to query these foreign keys, you can use an accumulator to accumulate the conditions that need to be queried and query the database.

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 4/22/2026

Support for. NET by operating system versions (250707 update)

Use virtual machines and test machines to test the support of each version of the operating system for. NET. After installing the operating system, it is passed by measuring the corresponding running time of the installation and being able to run the Stardust Agent.

继续阅读
同分类 / 同标签 2/7/2026

Summary of experience in using AOT

From the very beginning of project creation, you should develop a good habit of conducting AOT release testing in a timely manner whenever new features are added or newer syntax is used.

继续阅读