Applies multiple accumulators sequentially in a single pass over a sequence.
In the example below, Aggregate
is used to run the following seven
accumulators:
- sum of all numbers
- sum of even numbers
- count of numbers
- smallest number
- largest number
- distinct number of digits across all numbers
- list of numbers
concurrently, and in a single pass, over a sequence of integers:
Enumerable
.Range(1, 10)
.Shuffle()
.Select(n => new { Num = n, Str = n.ToString(CultureInfo.InvariantCulture) })
.Aggregate(
0, (s, e) => s + e.Num,
0, (s, e) => e.Num % 2 == 0 ? s + e.Num : s,
0, (s, _) => s + 1,
(int?)null, (s, e) => s is int n ? Math.Min(n, e.Num) : e.Num,
(int?)null, (s, e) => s is int n ? Math.Max(n, e.Num) : e.Num,
new HashSet<int>(), (s, e) => { s.Add(e.Str.Length); return s; },
new List<(int, string)>(), (s, e) => { s.Add((e.Num, e.Str)); return s; },
(sum, esum, count, min, max, lengths, items) => new
{
Sum = sum,
EvenSum = esum,
Count = count,
Average = (double)sum / count,
Min = min is int mn ? mn : throw new InvalidOperationException(),
Max = max is int mx ? mx : throw new InvalidOperationException(),
UniqueLengths = "[" + string.Join(", ", lengths) + "]",
Items = "[" + string.Join(", ", items) + "]",
})
Writing each aggregator this way can be tedious, repetitive and error-prone
because you cannot, for example, reuse Enumerable.Sum
but there is
a set of experimental overloads (that live in the
MoreLinq.Experimental
namespace) that allow aggregators to be written
as reactive comprehensions. This enables you to use aggregators from
System.Reactive. The next example is logically the same as the previous,
except it uses the overload where aggregators from System.Reactive are reused.
Enumerable
.Range(1, 10)
.Shuffle()
.Select(n => new { Num = n, Str = n.ToString(CultureInfo.InvariantCulture) })
.Aggregate(
s => s.Sum(e => e.Num),
s => s.Select(e => e.Num).Where(n => n % 2 == 0).Sum(),
s => s.Count(),
s => s.Min(e => e.Num),
s => s.Max(e => e.Num),
s => s.Select(e => e.Str.Length).Distinct().ToArray(),
s => s.ToList(),
(sum, esum, count, min, max, lengths, items) => new
{
Sum = sum,
EvenSum = esum,
Count = count,
Average = (double)sum / count,
Min = min,
Max = max,
UniqueLengths = "[" + string.Join(", ", lengths) + "]",
Items = "[" + string.Join(", ", items) + "]",
})
For more details, see the documentation.
✏ Edit this page if you see a typo or wish to contribute an improvement. Alternatively, you can also report an issue you see.