程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> c#擴展方法奇思妙用高級篇二:Aggregate擴展其改進(2)

c#擴展方法奇思妙用高級篇二:Aggregate擴展其改進(2)

編輯:關於C語言

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

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

Aggregate

public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func)
{
 using (IEnumerator<TSource> enumerator = source.GetEnumerator())
 {
  enumerator.MoveNext();
  TSource current = enumerator.Current;
  while (enumerator.MoveNext())
   current = func(current, enumerator.Current);
  return current;
 }
}

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

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

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

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

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

//改進的Aggerate擴展(示例代碼,實際使用請添加空值檢查)
public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, int, TSource> func)
{
 int index = 0;
 using (IEnumerator<TSource> enumerator = source.GetEnumerator())
 {
  enumerator.MoveNext();
  index++;
  TSource current = enumerator.Current;
  while (enumerator.MoveNext())
   current = func(current, enumerator.Current, index++);
  return current;
 }
}

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

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

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

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

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved