// 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);
或者也许在字符串序列中总结字符串的所有长度:
int total = sequence.Aggregate(0, (current, item) => current + item.Length);
var numbers = new List<int> { 6, 2, 8, 3 };
int sum = numbers.Aggregate(func: (result, item) => result + item);
// sum: (((6+2)+8)+3) = 19
在此示例中,传递了命名方法Add而不是lambda表达式 .
var numbers = new List<int> { 6, 2, 8, 3 };
int sum = numbers.Aggregate(func: Add);
// sum: (((6+2)+8)+3) = 19
private static int Add(int x, int y) { return x + y; }
var list = new List<Student>();
var sorted = list
.OrderBy(s => s.LastName)
.ThenBy(s => s.FirstName)
.ThenBy(s => s.Age)
.ThenBy(s => s.Grading)
.ThenBy(s => s.TotalCourses);
var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate( (a,b) => a + ',' + b);
Console.WriteLine(csv); // Output a,b,c,d
这种方式大致相同 . 连接 a 一个逗号和 b 来制作 a,b . 然后用逗号和 c 连接 a,b 以制作 a,b,c . 等等 .
Example 3. Multiplying numbers using a seed
为了完整性,_452200_的_452200_取一个种子值 .
var multipliers = new []{10,20,30,40};
var multiplied = multipliers.Aggregate(5, (a,b) => a * b);
Console.WriteLine(multiplied); //Output 1200000 ((((5*10)*20)*30)*40)
11 回答
一个简短而重要的定义可能是这样的:Linq Aggregate扩展方法允许声明一种应用于列表元素的递归函数,其操作数是两个:元素按它们出现在列表中的顺序,一次一个元素,以及先前递归迭代的结果,如果还没有递归,则没有任何内容 .
通过这种方式,您可以计算数字的阶乘,或连接字符串 .
这部分取决于你所谈论的超载,但基本思路是:
从种子开始"current value"
迭代序列 . 对于序列中的每个值:
应用用户指定的函数将
(currentValue, sequenceValue)
转换为(nextValue)
设置
currentValue = nextValue
返回最终
currentValue
您可能会发现Aggregate post in my Edulinq series很有用 - 它包含更详细的描述(包括各种重载)和实现 .
一个简单的例子是使用
Aggregate
作为Count
的替代:或者也许在字符串序列中总结字符串的所有长度:
就个人而言,我很少发现
Aggregate
很有用 - "tailored"聚合方法对我来说通常都足够好 .Aggregate主要用于分组或汇总数据 .
根据MSDN“聚合函数在序列上应用累加器函数” .
示例1:添加数组中的所有数字 .
变量解释
total:它将保存func返回的总和值(聚合值) .
nextValue:它是数组序列中的下一个值 . 将该值加到聚合值上,即总数 .
示例2:添加数组中的所有项 . 同时将初始累加器值设置为从10开始添加 .
论点解释:
第一个参数是初始值(起始值,即种子值),它将用于开始添加数组中的下一个值 .
第二个参数是一个func,它是一个带有2个int的函数 .
1.total:这将与计算后func返回的总和值(聚合值)之前相同 .
2.nextValue ::它是数组序列中的下一个值 . 将该值加到聚合值上,即总数 .
同时调试此代码将使您更好地了解聚合的工作方式 .
除了这里已经有的所有优秀答案之外,我还使用它来完成一系列转换步骤 .
如果将转换实现为
Func<T,T>
,则可以向List<Func<T,T>>
添加多个转换,并使用Aggregate
通过每个步骤遍历T
的实例 .一个更具体的例子
您希望获取
string
值,并进行一系列可以以编程方式构建的文本转换 .这将创建一个转换链:删除前导和尾随空格 - >删除第一个字符 - >删除最后一个字符 - >转换为大写 . 可以根据需要添加,删除或重新排序此链中的步骤,以创建所需的任何类型的转换管道 .
这个特定管道的最终结果是
" cat "
变为"A"
.一旦你意识到
T
可以是任何东西,这会变得非常强大 . 这可以用于图像转换,如过滤器,使用BitMap
作为示例;从Jamiec's回答了很多 .
如果唯一需要生成CSV字符串,您可以试试这个 .
这是一个包含100万个字符串的测试
源代码是here
每个人都给出了他的解释 . 我的解释就是这样 .
Aggregate方法将函数应用于集合的每个项目 . 例如,让我们有集合{6,2,8,3}和函数Add(运算符)它(((6 2)8)3)并返回19
在此示例中,传递了命名方法Add而不是lambda表达式 .
这是关于在诸如Linq Sorting之类的Fluent API上使用
Aggregate
的说明 .并且让我们看看我们想要实现一个带有一组字段的sort函数,这很容易使用
Aggregate
而不是for循环,如下所示:我们可以像这样使用它:
Super short 聚合在Haskell / ML / F#中像折叠一样工作 .
Slightly longer .Max(),. Min(),. Sum(),. . Average()都迭代序列中的元素,并使用相应的聚合函数聚合它们 . .Aggregate()是通用聚合器,它允许开发人员指定开始状态(又名种子)和聚合函数 .
我知道你要求一个简短的解释,但我当其他人给出了几个简短的答案时,我想你可能会对稍微长一点感兴趣
Long version with code 一种方式来说明它可以显示如何使用foreach和使用.Aggregate实现Sample Standard Deviation . 注意:我没有优先考虑性能,所以我不必要地在集合上多次迭代
首先是一个辅助函数,用于创建二次距离之和:
然后使用ForEach进行样本标准偏差:
然后一旦使用.Aggregate:
请注意,除了如何计算sumOfQuadraticDistance之外,这些函数是相同的:
与:
那么.Aggregate所做的就是它封装了这个聚合器模式,我希望.Aggregate的实现看起来像这样:
使用标准差函数看起来像这样:
IMHO
那么.Aggregate有助于提高可读性吗?一般来说,我喜欢LINQ,因为我认为 . 在哪里, . 选择,.OrderBy等大大提高了可读性(如果你避免内联的hierarhical . 选择) . 由于完整性的原因,Aggregate必须在Linq中,但我个人并不是那么相信.Aggregate与一个写得很好的foreach相比增加了可读性 .
Aggregate用于对多维整数数组中的列求和
在Aggregate func中使用带索引的select来对匹配的列求和并返回一个新的Array; {3 2 = 5,1 4 = 5,7 16 = 23,8 5 = 13} .
但是计算布尔数组中的trues数量更加困难,因为累积类型(int)与源类型(bool)不同;这里种子是必要的,以便使用第二次过载 .
Aggregate
最容易理解的定义是它对列表的每个元素执行一个操作,同时考虑到之前的操作 . 也就是说它对第一个和第二个元素执行操作并向前传递结果 . 然后它对前一个结果和第三个元素进行操作并继续前进 . 等等Example 1. Summing numbers
这会增加
1
和2
来制作3
. 然后添加3
(前一个结果)和3
(序列中的下一个元素)以生成6
. 然后添加6
和4
来制作10
.Example 2. create a csv from an array of strings
这种方式大致相同 . 连接
a
一个逗号和b
来制作a,b
. 然后用逗号和c
连接a,b
以制作a,b,c
. 等等 .Example 3. Multiplying numbers using a seed
为了完整性,_452200_的_452200_取一个种子值 .
与上面的示例非常相似,它以
5
的值开头,并将其乘以序列10
的第一个元素,得到50
的结果 . 该结果被继续并乘以序列20
中的下一个数字,得到1000
的结果 . 这继续通过序列的剩余2个元素 .实例:http://rextester.com/ZXZ64749
文件:http://msdn.microsoft.com/en-us/library/bb548651.aspx
Addendum
上面的示例2使用字符串连接来创建由逗号分隔的值列表 . 这是解释
Aggregate
使用的简单方法,这是本答案的意图 . 但是,如果使用此技术实际创建大量逗号分隔数据,则使用StringBuilder
更合适,并且这与Aggregate
完全兼容,使用种子重载来启动StringBuilder
.更新示例:http://rextester.com/YZCVXV6464
一张图片胜过千言万语
Enumerable.Aggregate有三个重载:
Overload 1:
例:
这种重载很简单,但它有以下限制:
序列必须包含至少一个元素,
否则该函数将抛出
InvalidOperationException
.元素和结果必须属于同一类型 .
Overload 2:
例:
这种过载更为通用:
必须提供种子值(
bIn
) .该集合可以为空,
在这种情况下,函数将生成种子值作为结果 .
元素和结果可以有不同的类型 .
Overload 3:
第三次超载对IMO来说不是很有用 .
通过使用重载2后跟一个转换其结果的函数,可以更简洁地编写相同的内容 .