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;
            }
        }
View Code

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
View Code

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);
View Code
或者将表达式提取成函数
        public static string IsMicrosoft(string bword, string aword)
        {
            return bword == "microsoft" ? "www." + bword + ".com" : bword + "\nwww." + aword + ".com";
        }
View Code
            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);
View Code

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);
            }
View Code
        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;
            }
        }
View Code

有一个问题,是没有含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);
                }
            }
View Code

 

总结:优点就是可以前后比较,不用写循环语句和临时变量。

而且可以把比较的逻辑提取出来变成一个方法,优化代码逻辑。

 

posted @ 2022-03-03 10:37  江境纣州  阅读(24)  评论(0编辑  收藏  举报