System.Linq.Enumerable.Aggregate累加器
1、源码

public static TSource Aggregate<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> func) { if (source == null) throw Error.ArgumentNull("source"); if (func == null) throw Error.ArgumentNull("func"); using (IEnumerator<TSource> e = source.GetEnumerator()) { if (!e.MoveNext()) throw Error.NoElements(); TSource result = e.Current; while (e.MoveNext()) result = func(result, e.Current); return result; } }
2、调用

var list = new List<string>() { "A","B","C","D","E","F","G","H" }; var listString = list.Aggregate((bword, aword) => bword + aword); Console.WriteLine(listString); // ABCDEFGH
3、自定义
/// <summary> /// 对一个序列应用累加器函数 /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="source"></param> /// <param name="func"></param> /// <returns></returns> public static TSource AggregateDemo<TSource>(IEnumerable<TSource> source, Func<TSource, TSource, TSource> func) { if (source == null) throw new Exception("source Null"); if (func == null) throw new Exception("func Null"); using (IEnumerator<TSource> e = source.GetEnumerator()) { if (!e.MoveNext()) throw new Exception("source Null"); // 取第一个 TSource result = e.Current; while (e.MoveNext()) result = func(result, e.Current); // 取第二个 return result; } }
var list = new List<string>() { "A","B","C","D","E","F","G","H" }; var listString = AggregateDemo(list, (bword, aword) => bword + aword); Console.WriteLine(listString); // ABCDEFGH
TSource result = e.Current;第一个
while (e.MoveNext())// 取第二个
result = func(result, e.Current); // 将第二个累加到第一个上面,按照func自定义函数
4、案例1:

List<string> list = new List<string>() { "microsoft","yahoo","google","eBay","amazon","msn","youtube","flickr" }; var listString = list.Aggregate((bword, aword) => bword == "microsoft" ? "www." + bword + ".com" : bword + "\nwww." + aword + ".com"); Console.WriteLine("\n\n聚合转换:\n{0}", listString);
或者将表达式提取成函数

public static string IsMicrosoft(string bword, string aword) { return bword == "microsoft" ? "www." + bword + ".com" : bword + "\nwww." + aword + ".com"; }

List<string> list = new List<string>() { "microsoft","yahoo","google","eBay","amazon","msn","youtube","flickr" }; var listString = AggregateDemo(list, IsMicrosoft); Console.WriteLine("\n\n聚合转换:\n{0}", listString);
5、案例2:

using (var context = new KTStoreModel()) { context.Database.Log = Console.WriteLine; var products = context.ProductSet.ToList(); ProductSet maxprice = products.Aggregate(GetMaxE); Console.WriteLine(maxprice.Name + maxprice.Price); }

public static ProductSet GetMaxE(ProductSet bp, ProductSet ap) { if (bp.Name.Contains("E") && ap.Name.Contains("E")) { if (ap.Price > bp.Price) { return ap; } else { return bp; } } else if (bp.Name.Contains("E")) { return bp; } else if (ap.Name.Contains("E")) { return ap; } else { return ap; } }
有一个问题,是没有含E的数据,就会取到一个不是E的
可以用where,orderby

using (var context = new KTStoreModel()) { context.Database.Log = Console.WriteLine; var products = context.ProductSet.ToList(); var maxprice = products.Where(p => p.Name.Contains("E")).OrderBy(p=>p.Price).FirstOrDefault(); if (maxprice != null) { Console.WriteLine(maxprice.Name + maxprice.Price); } }
总结:优点就是可以前后比较,不用写循环语句和临时变量。
而且可以把比较的逻辑提取出来变成一个方法,优化代码逻辑。