提高linq代码效率的Aggregate方法

  如果你不是初出茅庐,相信大家对linq的基本用法很熟悉吧,自从有了linq使用foreach的频率少多了,今天这篇文章介绍用Aggregate提高linq的查询效率。

正题

    微软官网的解释是:对序列应用累加器函数。将指定的种子值用作累加器的初始值,并使用指定的函数选择结果值。我们不看概念,下面用列子说明Aggregate的用法。需求是找出字符串数组中最长的单词。.

 // 自定义string数组,随机5个单词string[] words = { "Hello", "World", "Program", "CSharp", "Linq" };

如果没有Aggregate方法通常是是用foreach循环比较来解决。用Aggregate很简单一句代码就可以实现。​​​​​​​

string longName =words.Aggregate((lang, next) => lang.Length > next.Length ? lang : next); Console.WriteLine(longName); //输出:Program

如果需求增加点难度,要求比Hello长的字符串做比较,如果比Hello小的话返回Hello?可以如下实现​​​​​​​

 string longName2 = words.Aggregate("Hello", (lang, next) =>            lang.Length > next.Length ? lang : next,             word => word.ToUpper()             //返回大写的最大长度单词并转成大写            );            Console.WriteLine(longName);            //输出:Program          string[] words2 = { "Hello", "Worl", "Pro", "CS", "Lin" };           string longName3 = words2.Aggregate("Hello", (lang, next) =>            lang.Length > next.Length ? lang : next,             word => word.ToUpper() //返回大写的最大长度单词并转成大写            );            Console.WriteLine(longName3);            //输出:Hello

Aggregate使对一系列值执行计算变得简单。此方法的工作原理是为每个元素source调用func一次。每次调用时 func ,都会将序列中的元素和聚合值 (作为第一个参数 func 传递给) 。参数的值 seed 用作初始聚合值。替换上一个聚合值的结果 func 。

以上是使用场景的第一种,下面介绍另一场景,需求是在一个int数组找出偶数的个数,并从种子1开始计算。​​​​​​​

   // 自定义int数组int[] ints = { 1, 2, 8, 0, 1, 3,8,9 };int numEven = ints.Aggregate(1, (total, next) =>        next % 2 == 0 ? total + 1 : total);Console.WriteLine("偶数个数为: {0}", numEven);//结果为5//Aggregate第一个参数1为种子参数,如果为0则是4

结语

    其实Aggregate底层源码实现也会有foreach,感兴趣的可以反编译查看一下。