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

  • 相关阅读:
    WIKI 配置参数
    SSH远程错误或者登录解决方法
    Mysql my.conf配置说明
    Mysql 常用命令
    Nginx 开机启动
    排序的总结
    strcpy函数实现(转载)
    函数指针传递
    地址的强制转换
    结构体内存对齐
  • 原文地址:https://www.cnblogs.com/liao-hua/p/4575725.html
Copyright © 2011-2022 走看看