LINQ-資料彙總好物Aggregate()

平常公司都會有匯出報表的功能,通常這類型資料都可以在SQL中完成。

EX:該月業績最好的業務員

1月 小王 (30筆訂單)

2月 小陳 (40筆訂單)

3月 小林 (20筆訂單)

類似這樣的資料在SQL中只需要GROUP + MAX就可以完成,使用LINQ時候也是GROUP + COUNT就可以完成。

 

但如果情境變成NOSQL,沒有GROUP這種函數,並且要呈現的資料為

「當月業績最好的人,並算出  該月  的 每日業績總額」

就會變成依據月份來算每日Total,此時使用SUM也不是、MAX也不是,往往就是跑for迴圈,給予初始值,月份結束時候重新計算,其實可以不用這麼麻煩,可以透過Aggregate()來幫我們處理。

 


參考連結

奎Kuei的LINQ - Aggregate()

91大的[.NET]快快樂樂學LINQ系列-Aggregate() 簡介

 


這段是在介紹Aggregate中,三個參數個別的用途

1.seed:初始值

2.func:呼叫的函式(seed, item)

這邊的seed是來自於上一筆資料的seed,如果不懂得等等看範例就知道了。

item就是foreach的當前資料

3.resultSelector:依據seed + func處理後,取得的最終結果

 


這段在介紹Aggregate可以使用的多載方法,建議開個主控台應用程式跟著步驟1、2、3做一次會比較容易理解

1.Aggregate(func):不給初始值

            List<string> numbers = new List<string> { "6", "2", "8", "3" };
            string tmp = numbers.Aggregate(
             func: (seed, item) => seed + "*" + item
            );

            Console.WriteLine(tmp);

第一次 null + "*" + "6" = "6"

註※這邊理應會變成 "*" + 6,推測是因為seed沒給預設值,所以第一次並未執行,並把6的值傳給seed,如果理解有誤還請告知。

第二次 "6" + "*" + "2" = "6*2"

第三次 "6*2" + "*" + "8" = "6*2*8"

所以第四次理應變成"6*2*8*3",執行看看結果吧!

 

2.Aggregate(seed, func)

            List<string> numbers2 = new List<string> { "6", "2", "8", "3" };
            string tmp2 = numbers2.Aggregate(
             seed: "1",  func: (seed, item) => seed + "*" + item
            );

            Console.WriteLine(tmp2);

這邊由於有初始值,所以第一次的運算式會是

"1" + "*" + "6"

後續的執行方式參照方法1

所以印出來的結果會是"1*6*2*8*3"

3.Aggregate(seed, func, resultSelector)

            List<int> numbers3 = new List<int> { 6, 2, 8, 3 };
            double tmp3 = numbers3.Aggregate(
                seed: 0,
                func: (result, item) => result + item,
                resultSelector: result => (double)result / numbers.Count);

            Console.WriteLine(tmp3);

根據這次的資料處理,得到的最後結果為19。將其轉型為double,並除上COUNT,得到的結果為4.75

 


依據這個上面所了解的,再加以變形就可以做到SUM、AVG、MAX、MIN的效果了,也就是說每個月業績最高(GROUP)的每日業績總額(Aggregate)就可以做出來了。

SUM:

            List<int> numbers4 = new List<int> { 6, 2, 8, 3 };
            double tmp4 = numbers4.Aggregate(
                seed: 0,
                func: (result, item) => result + item);

            Console.WriteLine(tmp4);

AVG(範例3):

            List<int> numbers3 = new List<int> { 6, 2, 8, 3 };
            double tmp3 = numbers3.Aggregate(
                seed: 0,
                func: (result, item) => result + item,
                resultSelector: result => (double)result / numbers.Count);

MAX:

            List<int> numbers5 = new List<int> { 6, 2, 8, 3 };
            int tmp5 = numbers5.Aggregate(
                seed: 0,
                // 透過三元運算子做大小的比較,來決定要留下哪個數值
                func: (result, item) => result > item ? result: item);

            Console.WriteLine(tmp5);

MIN:

            List<int> numbers6 = new List<int> { 6, 2, 8, 3 };
            int tmp6 = numbers6.Aggregate(
                // 透過三元運算子做大小的比較,來決定要留下哪個數值
                func: (result, item) => result < item ? result: item);

            Console.WriteLine(tmp6);

感謝專心寫好程式 奎大耐心指導,今日滿載而歸,謝謝!

 


LINE討論群FB討論區

歡迎您的加入,讓這個社群更加美好!

聯絡方式:
FaceBook
E-Mail