zoukankan      html  css  js  c++  java
  • Aggregate

    LINQ provides several aggregation extension methods: Aggregate, Average, Count, LongCount, Max, Min and Sum. The aggregation methods all take a list of objects and reduces that list to a single result. Conceptually it helps to think of Aggregate as a generic building block and the others aggregation methods (Average, Max, etc.) as special cases of Aggregate. In functional programming languages, such as F#, Aggregate is usually named fold (or inject in Ruby). The SQL like name Aggregate leads developers to write off Aggregate as purely for numeric aggregation purposes. In fact, Aggregate can be used whenever we want to build a single object from a group of objects.

    So how does Aggregate work?

    Looking at the Aggregate method signature is a pretty scary experience:

    public static TAccumulate Aggregate<TSource, TAccumulate>(
    	this IEnumerable<TSource> source,
    	TAccumulate seed,
    	Func<TAccumulate, TSource, TAccumulate> func
    )

    The Aggregate methods takes a list of source objects, a seed value and an accumulator function which it processes as follows:

    • The accumulator function is called for each item in the list and returns a value
    • The first time the accumulator function is called the seed and the first item in the list are passed to it
    • The accumulator function is called again with the result of the first accumulator function call and the second item in the list as its parameters
    • This continues until all items in the list are processed
    • The result of the last call to the accumulator function is returned as the result of the entire Aggregate method

    This can take some getting your head around. Here is an example:

    var whiskeyNames = new [] {"Ardbeg 1998", "Glenmorangie","Talisker", "Cragganmore"};
    
    var listOfWhiskies = whiskeyNames.Aggregate("Whiskies: ", (accumulated, next) =>
    {
    	Console.Out.WriteLine("(Adding [{0}] to the list [{1}])", next, accumulated);
    	return accumulated + " " + next;
    });
    
    Console.Out.WriteLine(listOfWhiskies);
    

    This outputs:

    (Adding [Ardbeg 1998] to the list [Whiskies: ])
    (Adding [Glenmorangie] to the list [Whiskies:  Ardbeg 1998])
    (Adding [Talisker] to the list [Whiskies:  Ardbeg 1998 Glenmorangie])
    (Adding [Cragganmore] to the list [Whiskies:  Ardbeg 1998 Glenmorangie Talisker])
    Whiskies:  Ardbeg 1998 Glenmorangie Talisker Cragganmore

    The seed parameter is optional. If it is omitted the first two items in the list will be passed to the function, as this example demonstrates:

    listOfWhiskies = whiskeyNames.Aggregate((accumulated, next) =>
    {
    	Console.Out.WriteLine("(Adding [{0}] to the list [{1}])", next, accumulated);
    	return accumulated + " " + next;
    });
    
    Console.Out.WriteLine(listOfWhiskies);
    

    This outputs:

    (Adding [Glenmorangie] to the list [Ardbeg 1998])
    (Adding [Talisker] to the list [Ardbeg 1998 Glenmorangie])
    (Adding [Cragganmore] to the list [Ardbeg 1998 Glenmorangie Talisker])
    Ardbeg 1998 Glenmorangie Talisker Cragganmore

    Finding the best item in a list

    Whiskey mostExpensiveWhiskey = whiskies.Aggregate((champion, challenger) => challenger.Price > champion.Price ? challenger : champion);
    Console.WriteLine("Most expensive is {0}", mostExpensiveWhiskey.Name);

    Creating a new ‘aggregated’ object

    var blendedWhiskey = whiskies.Where(x=> x.Country == "Scotland")
    .Aggregate(new Whiskey() { Name="Tesco value whiskey", Age=3, Country="Scotland" },
    	(newWhiskey, nextWhiskey) =>
    	{
    		newWhiskey.Ingredients.Add(nextWhiskey);
    		newWhiskey.Price += (nextWhiskey.Price / 10);
    		return newWhiskey;
    	});

    Alternative to Cunt

    // 0 is the seed, and for each item, we effectively increment the current value.
    // In this case we can ignore "item" itself.
    int count = sequence.Aggregate(0, (current, item) => current + 1);

    Summing numbers

    var nums = new[]{1,2,3,4};
    var sum = nums.Aggregate( (a,b) => a + b);
    Console.WriteLine(sum); // output: 10 (1+2+3+4)

    Note:

    the aggregate result type an seed type is the same. You can use lambda expresion or lambda statement(need return) as accumulate function.

    Reference:

    1. Refactoring to LINQ Part 2: Aggregate is Great

    2. LINQ Aggregate algorithm explained

    3. Reimplementing LINQ to Objects: Part 13 – Aggregate

  • 相关阅读:
    [转载][开源框架推荐]VTDXML:世界上最快的XML处理框架
    iptables规则的查看、添加、删除和修改
    [转载]Linux大文件传输
    nginx+ php 安装配置实用
    wojilu框架代码分析之ActionProcessor.Process()
    数据库范式通俗理解,谈谈数据库设计
    我记录综合系统学习研究之用户管理二(wojilu.Web.Controller.Users MainController)
    我记录学习研究之前端开发二(js基于1.8版)
    我记录综合系统学习研究之开篇
    我记录综合系统学习研究之用户管理一(wojilu.Web.Controller.Users MainController)
  • 原文地址:https://www.cnblogs.com/liao-hua/p/4575725.html
Copyright © 2011-2022 走看看