在Linq中有一些這樣的操做,根據集合計算某一單一值,好比集合的最大值,最小值,平均值等等。Linq中包含7種操做,這7種操做被稱做聚合操做。數組
一、Count操做,計算序列中元素的個數,或者計算知足必定條件的元素的個數函數
二、Sum操做,計算序列中全部元素的值的總和源碼分析
三、Max操做,計算序列中元素的最大值this
四、Min操做,計算序列中元素的最小值spa
五、Average操做,計算序列中全部元素的平均值code
六、Aggregate操做,對集合中的元素進行自定義的聚合計算blog
七、LongCount操做,計算集合中的元素的數量,或者知足必定條件的元素的數量,通常用來計算大型集合中元素的數量原型
下面咱們就來對這些聚合操做來作逐一的分析。源碼
Count操做it
Count操做是用來計算序列中元素的數量或者知足必定條件的元素的數量。Count()方法的原型:
public static int Count<TSource>(this IEnumerable<TSource> source); public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
Count方法有2個原型,第一個只是單獨的計算序列中的元素的數量總和,第二個原型有一個委託函數,用來篩選知足必定條件的元素,而後再計算知足條件的數量和。下面咱們舉個例子來講明:
1 private void CountQuery() 2 { 3 int[] ints = new int[] { 1,2,3,4,5,6,7 }; 4 5 6 var result = ints.Count(); 7 var result2 = ints.Count(x => x > 4); 8 9 Response.Write(result + "</br>"); 10 11 Response.Write(result2 + "</br>"); 12 13 }
這個例子中result是計算ints數組的總數量,result計算的是ints中元素值大於4的元素個數。
看看運行結果:
這種求和過程也很簡單
Sum操做
Sum操做計算序列中全部元素的和。Sum函數的原型比較多,這裏不一一列舉。看例子:
1 private void SumQuery() 2 { 3 int[] ints = new int[] { 1,2,3,4,5,6,7 }; 4 5 6 var result = ints.Sum(); 7 8 9 Response.Write(result + "</br>"); 10 11 12 13 }
看看結果:
Max操做
Max操做來計算序列中元素的最大值。
1 private void MaxQuery() 2 { 3 int[] ints = new int[] { 1,2,3,4,5,6,7 }; 4 5 6 var result = ints.Max(); 7 8 9 Response.Write(result + "</br>"); 10 11 12 13 }
Min操做
Min操做來計算序列中元素的最小值。
1 private void MinQuery() 2 { 3 int[] ints = new int[] { 1,2,3,4,5,6,7 }; 4 5 6 var result = ints.Min(); 7 8 9 Response.Write(result + "</br>"); 10 11 12 13 }
Average操做
Average操做是計算序列的全部元素的平均值。
1 private void AverageQuery() 2 { 3 int[] ints = new int[] { 1,2,3,4,5,6,7 }; 4 5 6 var result = ints.Average(); 7 8 9 Response.Write(result + "</br>"); 10 11 12 13 }
Aggregate操做
Aggregate操做,上面的一些都比較簡單,咱們重點來分析一下Aggregate操做。Aggregate操做可以對集合中的元素進行自定義的聚合計算。Aggregate()函數有3種原型:
public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func); public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func); public static TResult Aggregate<TSource, TAccumulate, TResult>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func, Func<TAccumulate, TResult> resultSelector);
其中source表示數據源,func表示累加器函數,seed表示累加器的初始值,resultSelector表示轉換結果函數。
下面咱們用一個詳細的例子來分累加是如何操做的。
首先咱們建立一個整型數組ints,值是0~99.
使用Aggregate計算ints中的素有元素之和。
1 private void AggregateQuery() 2 { 3 int[] ints = new int[100]; 4 5 for (int i = 0; i < 100; i++) 6 { 7 ints[i]=i; 8 } 9 10 var result = ints.Aggregate((a,b) => a+b); 11 12 13 Response.Write(result + "</br>"); 14 15 16 17 }
計算結果:
咱們看第一個原型的累加過程:
最終就是經過遍歷數據源的每個元素,根據咱們傳如的累加函數來累加。好比咱們累加函數是求全部元素的和,那麼累加函數就是func(a,b){a+b},若是求全部元素的乘積,那麼累加函數就是func(a,b){a*b}.
參數a,b的意義:a表示當前元素以前的全部數據根據累加函數求得的值,b就是當前元素。
咱們看第二個累加原型:
第二個累加原型有一個累加基數seed,就表示在這個seed基礎上進行累加。好比上面咱們建立的數組是0~99,累加和是4950.那麼我給累加seed這個基數設置爲100,那麼累加和就是4950+100=5050.
1 private void AggregateQuery() 2 { 3 int[] ints = new int[100]; 4 5 for (int i = 0; i < 100; i++) 6 { 7 ints[i]=i; 8 } 9 10 var result = ints.Aggregate(100,(a,b) => a+b); 11 12 13 Response.Write(result + "</br>"); 14 15 16 17 }
看看結果:
看源碼分析也確實是這樣子的:
第三個原型又多了一個委託函數,這個委託函數是對累加的結果作進一步處理而後返回處理後的結果。咱們先看看源碼分析:
從累加原型的源碼看出,把最終的累加結果又傳給resultSelector方法進行進一步處理。
咱們看個簡單的例子:
1 private void AggregateQuery() 2 { 3 int[] ints = new int[100]; 4 5 for (int i = 0; i < 100; i++) 6 { 7 ints[i]=i; 8 } 9 10 var result = ints.Aggregate(100,(a,b) => a+b,x=>x*-1); 11 12 13 Response.Write(result + "</br>"); 14 15 16 17 }
從代碼能夠看出,咱們最終累加的值,而後對它乘以-1返回結果。咱們預測應該返回-5050.
看看結果:
看來咱們通過源碼分析,最終獲得了驗證,咱們的分析是正確的。
LongCount操做
LongCount和Count同樣,都是計算序列中元素的數量或者知足必定條件的元素的數量,通常longcount用來計算大型的集合。可是從源代碼中我沒看到LongCount和Count的計算方法有什麼不一樣,只是計算和的num的聲明不一樣,Count的num聲明爲int類型,而LongCount的num聲明爲long類型,數據範圍擴大了而已,這裏就再也不重複講解了,參考Count便可。