这听起来可能很蹩脚,但我还没能找到一个对聚合的真正好的解释。
好的意思是简短、描述性、全面,并有一个小而清晰的例子。
这听起来可能很蹩脚,但我还没能找到一个对聚合的真正好的解释。
好的意思是简短、描述性、全面,并有一个小而清晰的例子。
当前回答
这在一定程度上取决于你所说的过载,但基本的想法是:
以种子作为“当前值”开始重复序列。对于序列中的每个值:应用用户指定的函数将(currentValue,sequenceValue)转换为(nextValue)设置当前值=下一个值返回最终currentValue
你可能会发现我的Edulinq系列中的Aggregate文章很有用——它包含了更详细的描述(包括各种重载)和实现。
一个简单的例子是使用聚合作为计数的替代:
// 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);
就我个人而言,我很少发现聚合有用——“定制”的聚合方法通常对我来说足够好。
其他回答
从Jamiec的回答中学到了很多。
如果只需要生成CSV字符串,可以尝试此操作。
var csv3 = string.Join(",",chars);
这是一个100万个字符串的测试
0.28 seconds = Aggregate w/ String Builder
0.30 seconds = String.Join
源代码在这里
除了这里已经给出的所有好答案之外,我还用它来引导一个项目完成一系列转换步骤。
如果转换被实现为Func<T,T>,则可以将多个转换添加到List<Func<T,T>中,并使用Aggregate遍历T的每个步骤。
更具体的例子
您需要获取一个字符串值,并通过一系列可以通过编程构建的文本转换对其进行遍历。
var transformationPipeLine = new List<Func<string, string>>();
transformationPipeLine.Add((input) => input.Trim());
transformationPipeLine.Add((input) => input.Substring(1));
transformationPipeLine.Add((input) => input.Substring(0, input.Length - 1));
transformationPipeLine.Add((input) => input.ToUpper());
var text = " cat ";
var output = transformationPipeLine.Aggregate(text, (input, transform)=> transform(input));
Console.WriteLine(output);
这将创建一系列转换:删除前导和尾随空格->删除第一个字符->删除最后一个字符->转换为大写。可以根据需要添加、删除或重新排序此链中的步骤,以创建所需的任何类型的转换管道。
这个特定管道的最终结果是“猫”变成了“A”。
一旦你意识到T可以是任何东西,它就会变得非常强大。这可以用于图像转换,如过滤器,使用BitMap作为示例;
每个人都给出了自己的解释。我的解释是这样的。
聚合方法将函数应用于集合的每个项。例如,让我们使用集合{6,2,8,3}和它执行的函数Add(operator+)(((6+2)+8)+3),并返回19
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; }
用于对多维整数数组中的列求和的聚合
int[][] nonMagicSquare =
{
new int[] { 3, 1, 7, 8 },
new int[] { 2, 4, 16, 5 },
new int[] { 11, 6, 12, 15 },
new int[] { 9, 13, 10, 14 }
};
IEnumerable<int> rowSums = nonMagicSquare
.Select(row => row.Sum());
IEnumerable<int> colSums = nonMagicSquare
.Aggregate(
(priorSums, currentRow) =>
priorSums.Select((priorSum, index) => priorSum + currentRow[index]).ToArray()
);
在Aggregate函数中使用带索引的Select对匹配的列求和并返回新的Array;{ 3 + 2 = 5, 1 + 4 = 5, 7 + 16 = 23, 8 + 5 = 13 }.
Console.WriteLine("rowSums: " + string.Join(", ", rowSums)); // rowSums: 19, 27, 44, 46
Console.WriteLine("colSums: " + string.Join(", ", colSums)); // colSums: 25, 24, 45, 42
但是,由于累积类型(int)与源类型(bool)不同,因此计算布尔数组中的true数更为困难;这里需要种子以使用第二过载。
bool[][] booleanTable =
{
new bool[] { true, true, true, false },
new bool[] { false, false, false, true },
new bool[] { true, false, false, true },
new bool[] { true, true, false, false }
};
IEnumerable<int> rowCounts = booleanTable
.Select(row => row.Select(value => value ? 1 : 0).Sum());
IEnumerable<int> seed = new int[booleanTable.First().Length];
IEnumerable<int> colCounts = booleanTable
.Aggregate(seed,
(priorSums, currentRow) =>
priorSums.Select((priorSum, index) => priorSum + (currentRow[index] ? 1 : 0)).ToArray()
);
Console.WriteLine("rowCounts: " + string.Join(", ", rowCounts)); // rowCounts: 3, 1, 2, 2
Console.WriteLine("colCounts: " + string.Join(", ", colCounts)); // colCounts: 3, 2, 1, 2
聚合主要用于分组或汇总数据。
根据MSDN“聚合函数在序列上应用累加器函数。”
示例1:将数组中的所有数字相加。
int[] numbers = new int[] { 1,2,3,4,5 };
int aggregatedValue = numbers.Aggregate((total, nextValue) => total + nextValue);
*重要信息:默认情况下,初始聚合值是集合序列中的1元素。即:总变量初始值默认为1。
变量解释
total:它将保存func返回的合计值(聚合值)。
nextValue:它是数组序列中的下一个值。然后将该值添加到聚合值,即总计。
示例2:添加数组中的所有项。还设置初始累加器值,从10开始添加。
int[] numbers = new int[] { 1,2,3,4,5 };
int aggregatedValue = numbers.Aggregate(10, (total, nextValue) => total + nextValue);
参数说明:
第一个参数是初始值(起始值,即种子值),用于开始与数组中的下一个值相加。
第二个参数是一个func,它是一个取2int的func。
1.total:这将与计算后func返回的总和值(聚合值)之前保持相同。
2.nextValue::它是数组序列中的下一个值。然后将该值添加到聚合值,即总计。
此外,调试此代码将使您更好地了解聚合的工作方式。