成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C#擴展方法之Enumerable.Aggregate分析

開發 后端
本文介紹C#擴展方法Enumerable.Aggregate的使用。Aggregate是Enumerable類的第一個方法,但確是Enumerable里面相對復雜的方法。

Enumerable.Aggregate 擴展方法在System.Linq命名空間中,是Enumerable類的***個方法(按字母順序排名),但確是Enumerable里面相對復雜的方法。

MSDN對這個C#擴展方法的說明是:對序列應用累加器函數。備注中還有一些說明,大意是這個方法比較復雜,一般情況下用Sum、Max、Min、Average就可以了。

看看下面的代碼,有了Sum,誰還會用Aggregate呢!

  1. public static void Test1()  
  2. {  
  3.     int[] nums = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};  
  4.  
  5.     int sum1 = nums.Sum();  
  6.     int sum2 = nums.Aggregate((i,j)=>i+j);  
  7. }  

同是求和,Sum不再需要額外參數,而Aggregate確還要將一個lambda作為參數。因為用起來麻煩,操作太低級,Aggregate漸漸被大多人忽視了...

實際上Aggregate因為“低級”,功能確是很強大的,通過它可以簡化很多聚合運算。

首先來看對Aggregate組裝字符串的問題:

  1. public static void Test2()  
  2. {  
  3.     string[] words = new string[] { "Able""was""I""ere""I""saw""Elba"};  
  4.     string s = words.Aggregate((a, n) => a + " " + n);  
  5.     Console.WriteLine(s);  

輸出結果是:Able was I ere I saw Elba (注:出自《大國崛起》,狄娜***講述了拿破侖一句經典)。

當然考慮性能的話還是用StringBuilder吧,這里主要介紹用法。這個Sum做不到吧!

Aggregate還可以將所有字符串倒序累加,配合String.Reverse擴展可以實現整個句子的倒序輸出:

  1. public static void Test3()  
  2. {  
  3.     string[] words = new string[] { "Able""was""I""ere""I""saw""Elba"};  
  4.     string normal = words.Aggregate((a, n) => a + " " + n);  
  5.     string reverse = words.Aggregate((a, n) => n.Reverse() + " " + a);  
  6.  
  7.     Console.WriteLine("正常:" + normal);  
  8.     Console.WriteLine("倒置:" + reverse);  
  9. }  
  10. // 倒置字符串,輸入"abcd123",返回"321dcba"  
  11. public static string Reverse(this string value)  
  12. {  
  13.     char[] input = value.ToCharArray();  
  14.     char[] output = new char[value.Length];  
  15.     for (int i = 0; i < input.Length; i++)  
  16.         output[input.Length - 1 - i] = input[i];  
  17.     return new string(output);  
  18. }  

看下面,輸出結果好像不太對:

輸出結果 

怎么中間的都一樣,兩的單詞首尾字母大小寫發生轉換了呢?!

仔細看看吧,不是算法有問題,是輸入“有問題”。搜索一下“Able was I ere I saw Elba”,這可是很有名的英文句子噢!

Enumerable.Aggregate這個C#擴展方法還可以實現異或(^)操作:

  1. public static void Test4()  
  2. {  
  3.     byte[] data = new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35 };  
  4.     byte checkSum = data.Aggregate((a, n) => (byte)(a ^ n));  
  5. }  

對經常作串口通信的朋友比較實用。

看來Aggregate也是比較“簡單易用”的,深入一步來看看它是怎么實現的吧,使用Reflector,反編譯一下System.Core.dll。

以下代碼取自反編譯結果,為了演示刪除了其中的空值判斷代碼:

  1. public static TSource Aggregate(this IEnumerable source, Func func)  
  2.         {  
  3.             using (IEnumerator enumerator = source.GetEnumerator())  
  4.             {  
  5.                 enumerator.MoveNext();  
  6.                 TSource current = enumerator.Current;  
  7.                 while (enumerator.MoveNext())  
  8.                     current = func(current, enumerator.Current);  
  9.                 return current;  
  10.             }  
  11.         } 

也很簡單吧,就是一個循環!前面lambda表達式中參數a, n 分別對應current, enumerator.Current,對照一下,還是很好理解的。

現在我們想求整數數組中位置為偶數的數的和(間隔求和),可以用Where配合Sum:

  1. public static void Test5()  
  2. {  
  3.     int[] nums = new int[] { 10, 20, 30, 40, 50 };  
  4.     int sum1 = nums.Where((n, i) => i % 2 == 0).Sum();//10 + 30 + 50  

這個Where擴展設計的很好,它不但能帶出某項的值“n”,還能帶出項的位置“i”。

Aggregate可不行!我們來改進一下:

  1. //改進的Aggerate擴展(示例代碼,實際使用請添加空值檢查)  
  2. public static TSource Aggregate(this IEnumerable source, Funcint, TSource> func)  
  3. {  
  4.     int index = 0;  
  5.     using (IEnumerator enumerator = source.GetEnumerator())  
  6.     {  
  7.         enumerator.MoveNext();  
  8.         index++;  
  9.         TSource current = enumerator.Current;  
  10.         while (enumerator.MoveNext())  
  11.             current = func(current, enumerator.Current, index++);  
  12.         return current;  
  13.     }  

改進后的Aggregate更加強大,前面的求偶數位置數和的算法可以寫成下面的樣子:

  1. public static void Test6()  
  2. {  
  3.     int[] nums = new int[] { 10, 20, 30, 40, 50 };  
  4.     int sum2 = nums.Aggregate((a, c, i) => a + i%2 == 0 ? c : 0 );//10 + 30 + 50  

可能不夠簡潔,但它一個函數代替了Where和Sum。所在位置“i“的引入給Aggregate帶來了很多新的活力,也增加了它的應用范圍!

我隨筆《使用“初中知識”實現查找重復***算法 + 最***限算法》中***提出的“最***限算法”,用上這里改進的Aggregate擴展,也可以甩開Select和Sum,更加精簡一步了:

  1. public static void Test7()  
  2. {  
  3.     //1~n放在含有n+1個元素的數組中,只有唯一的一個元素值重復,最簡算法找出重復的數  
  4.     int[] array = new int[] { 1, 3, 2, 3, 4, 5 };  
  5.     //原極限算法  
  6.     int repeatedNum1 = array.Select((i, j) => i - j).Sum();  
  7.     //***極限算法  
  8.     int repeatedNum2 = array.Aggregate((a, n, i) => a + n - i);  
  9. }  

以上就介紹了C#擴展方法之Enumerable.Aggregate。本文來自鶴沖天的博客:《c#擴展方法奇思妙用高級篇二:Aggregate擴展其改進》。

【編輯推薦】

  1. 有關繼承與擴展方法之比較:ObservableCollection
  2. C#繼承知識詳解
  3. 淺談C#如何實現多繼承
  4. .NET 3.5擴展方法點評:優點與問題
  5. 淺析C#擴展方法
責任編輯:yangsai 來源: 鶴沖天
相關推薦

2009-08-10 17:36:17

C#擴展方法

2009-08-27 18:04:01

c#擴展方法string

2009-09-01 11:04:59

C#調用擴展方法

2009-08-31 14:45:10

C#擴展方法

2009-08-27 16:24:48

擴展方法C# 3.0新特性

2009-08-26 15:53:48

C#擴展方法

2009-08-18 14:14:45

C#擴展方法性能測試

2009-08-27 09:27:49

C#擴展方法

2012-10-31 17:37:48

2009-08-05 15:04:14

C# dll注入

2009-04-03 13:20:05

C#擴展方法調用

2009-09-01 11:19:47

C# 3.0擴展重載抉

2009-08-18 14:36:36

C# 操作Excel

2009-08-25 17:59:49

C#入門

2009-09-17 11:29:50

Linq擴展方法

2009-09-02 17:08:30

C#語言開發Windo

2009-08-28 14:25:57

C# byte數組

2009-08-26 17:16:22

C# CheckSta

2009-08-17 17:40:53

C# GetAllCu

2009-08-26 09:50:08

C# GreetPeo
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天操人人干 | 色免费看| 国产精品久久亚洲7777 | 亚洲精品电影 | 午夜精品久久久久久久星辰影院 | 日韩欧美国产精品综合嫩v 一区中文字幕 | 三区在线观看 | 免费黄色大片 | 粉色午夜视频 | 少妇精品亚洲一区二区成人 | 亚洲最新在线 | 台湾佬成人网 | 网页av| 精品国产乱码久久久久久图片 | 久久久网 | 成人在线观看免费视频 | www.国产日本 | 亚洲视频中文字幕 | 午夜激情视频在线 | 日韩精品a在线观看图片 | 日韩精品久久一区二区三区 | 亚洲在线一区 | 免费在线观看av的网站 | 久久久久久网站 | 国产精品一区二区无线 | 国产精品久久久久久久久久免费看 | 超碰在线观看97 | 国产精品久久久久久久久久久久午夜片 | 久久国产精品免费视频 | 国产二区视频 | 久久亚洲一区 | h漫在线观看 | 天堂久久天堂综合色 | 亚洲欧美国产毛片在线 | 九九九久久国产免费 | 亚洲国产精品久久久 | 国产精品久久久久久久模特 | 成人国产精品免费观看 | 久久精品国产亚洲 | 久久一区二区视频 | 国产欧美一区二区三区国产幕精品 |