码迷,mamicode.com
首页 > 其他好文 > 详细

Aggregate

时间:2015-06-14 22:34:58      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:

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

Aggregate

标签:

原文地址:http://www.cnblogs.com/liao-hua/p/4575725.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!