Enumerable.Aggregate 擴展方法在System.Linq命名空間中,是Enumerable類的第一個方法(按字母順序排名),但確是Enumerable裡面相對復雜的方法。
MSDN對它的說明是:對序列應用累加器函數。備注中還有一些說明,大意是這個方法比較復雜,一般情況下用Sum、Max、Min、Average就可以了。
看看下面的代碼,有了Sum,誰還會用Aggregate呢!
public static void Test1()
{
int[] nums = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum1 = nums.Sum();
int sum2 = nums.Aggregate((i,j)=>i+j);
}
同是求和,Sum不再需要額外參數,而Aggregate確還要將一個lambda作為參數。因為用起來麻煩,操作太低級,Aggregate漸漸被大多人忽視了...
實際上Aggregate因為“低級”,功能確是很強大的,通過它可以簡化很多聚合運算。
首先來看對Aggregate組裝字符串的問題:
public static void Test2()
{
string[] Words = new string[] { "Able", "was", "I", "ere", "I", "saw", "Elba"};
string s = Words.Aggregate((a, n) => a + " " + n);
Console.WriteLine(s);
}
輸出結果是:Able was I ere I saw Elba (注:出自《大國崛起》,狄娜最後講述了拿破侖一句經典)。
當然考慮性能的話還是用StringBuilder吧,這裡主要介紹用法。這個Sum做不到吧!
Aggregate還可以將所有字符串倒序累加,配合String.Reverse擴展可以實現整個句子的倒序輸出:
public static void Test3()
{
string[] Words = new string[] { "Able", "was", "I", "ere", "I", "saw", "Elba"};
string normal = Words.Aggregate((a, n) => a + " " + n);
string reverse = Words.Aggregate((a, n) => n.Reverse() + " " + a);
Console.WriteLine("正常:" + normal);
Console.WriteLine("倒置:" + reverse);
}
// 倒置字符串,輸入"abcd123",返回"321dcba"
public static string Reverse(this string value)
{
char[] input = value.ToCharArray();
char[] output = new char[value.Length];
for (int i = 0; i < input.Length; i++)
output[input.Length - 1 - i] = input[i];
return new string(output);
}
看下面,輸出結果好像不太對:
怎麼中間的都一樣,兩的單詞首尾字母大小寫發生轉換了呢?!
仔細看看吧,不是算法有問題,是輸入“有問題”。搜索一下“Able was I ere I saw Elba”,這可是很有名的英文句子噢!
Aggregate還可以實現異或(^)操作:
public static void Test4()
{
byte[] data = new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35 };
byte checkSum = data.Aggregate((a, n) => (byte)(a ^ n));
}
對經常作串口通信的朋友比較實用。