LINQ聚合算法解释

11 浏览
0 Comments

LINQ聚合算法解释

这听起来可能有点乏味,但是我还没有找到一个真正好的关于Aggregate的解释。

好的解释应该是简洁、明确、全面的,并有一个小而清晰的例子。

admin 更改状态以发布 2023年5月21日
0
0 Comments

具体取决于你所谈论的是哪种过载,但基本思想是:

  • 从一个种子值开始作为“当前值”
  • 迭代整个序列。对于序列中的每个值:
    • 应用用户指定的函数将(currentValue,sequenceValue)转换为(nextValue)
    • 设置currentValue = nextValue
  • 返回最终的currentValue

您可能会发现我在Edulinq系列中的Aggregate帖子非常有用-它包括更详细的描述(包括各种过载)和实现。

一个简单的例子是使用Aggregate作为Count的替代方法:

// 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);

个人而言,我很少觉得Aggregate有用-“定制”的聚合方法通常对我来说已经足够好了。

0
0 Comments

聚合操作最容易理解的定义是它对列表中的每个元素执行一个操作,考虑之前执行的操作。也就是说,它对第一个和第二个元素执行操作,并将结果向前传递。然后它对先前的结果和第三个元素执行操作,以此类推。

例1.求和

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

这将12相加得到3。然后将3(前一个结果)和3(序列中的下一个元素)相加得到6。然后将64相加得到10

例2.从字符串数组创建csv

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。然后将a,b与逗号和c连接起来,得到a,b,c。以此类推。

例3.使用初始值乘以数字

为了完整起见,Aggregate有一个接受种子值的重载版本

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)

与上面的例子类似,这个例子从一个值5开始,并将其乘以序列的第一个元素10,得到一个结果50。这个结果被沿着序列传递,并乘以序列中的下一个数字20,得到一个结果1000。这将继续执行剩下的两个序列元素。

在线示例:http://rextester.com/ZXZ64749
文档:http://msdn.microsoft.com/en-us/library/bb548651.aspx


附加说明

以上示例2使用字符串连接创建了由逗号分隔的值列表。这只是解释使用Aggregate的一种简单方式,这也是本答案的意图。然而,如果使用此技术实际上创建大量逗号分隔的数据,更适合使用StringBuilder,并且完全兼容使用种子重载来初始化StringBuilderAggregate

var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate(new StringBuilder(), (a,b) => {
    if(a.Length>0)
        a.Append(",");
    a.Append(b);
    return a;
});
Console.WriteLine(csv);

已更新示例:http://rextester.com/YZCVXV6464

0