Template std.algorithm.iteration.reduce
Implements the homonym function (also known as accumulate
, compress
, inject
, or foldl
) present in various programming
languages of functional flavor. The call
first assigns reduce
!(fun)(seed,
range)seed
to an internal variable result
,
also called the accumulator. Then, for each
element x
in range
, result = fun(result, x)
gets evaluated. Finally, result
is returned. The one-argument version
works similarly, but it uses the first element of the range as the
seed (the range must be non-empty).
reduce
!(fun)(range)
Arguments
template reduce(fun...);
Functions
Function name | Description |
---|---|
reduce |
Returns
the accumulated result
See Also
sum
is similar to
that offers
precise summing of floating point numbers.
reduce
!((a, b) => a + b)
Example
Many aggregate range operations turn out to be solved with
quickly and easily. The example below illustrates reduce
's
remarkable power and flexibility.
reduce
import std.algorithm.comparison : max, min; import std.math : approxEqual; import std.range; int[] arr = [ 1, 2, 3, 4, 5 ]; // Sum all elements auto sum = reduce!((a,b) => a + b)(0, arr); assert(sum == 15); // Sum again, using a string predicate with "a" and "b" sum = reduce!"a + b"(0, arr); assert(sum == 15); // Compute the maximum of all elements auto largest = reduce!(max)(arr); assert(largest == 5); // Max again, but with Uniform Function Call Syntax (UFCS) largest = arr.reduce!(max); assert(largest == 5); // Compute the number of odd elements auto odds = reduce!((a,b) => a + (b & 1))(0, arr); assert(odds == 3); // Compute the sum of squares auto ssquares = reduce!((a,b) => a + b * b)(0, arr); assert(ssquares == 55); // Chain multiple ranges into seed int[] a = [ 3, 4 ]; int[] b = [ 100 ]; auto r = reduce!("a + b")(chain(a, b)); assert(r == 107); // Mixing convertible types is fair game, too double[] c = [ 2.5, 3.0 ]; auto r1 = reduce!("a + b")(chain(a, b, c)); assert(approxEqual(r1, 112.5)); // To minimize nesting of parentheses, Uniform Function Call Syntax can be used auto r2 = chain(a, b, c).reduce!("a + b"); assert(approxEqual(r2, 112.5));
Example
Sometimes it is very useful to compute multiple aggregates in one pass.
One advantage is that the computation is faster because the looping overhead
is shared. That's why
accepts multiple functions.
If two or more functions are passed, reduce
returns a
reduce
std.typecons.Tuple
object
with one member per passed-in function.
The number of seeds must be correspondingly increased.
import std.algorithm.comparison : max, min; import std.math : approxEqual, sqrt; import std.typecons : tuple, Tuple; double[] a = [ 3.0, 4, 7, 11, 3, 2, 5 ]; // Compute minimum and maximum in one pass auto r = reduce!(min, max)(a); // The type of r is Tuple!(int, int) assert(approxEqual(r[0], 2)); // minimum assert(approxEqual(r[1], 11)); // maximum // Compute sum and sum of squares in one pass r = reduce!("a + b", "a + b * b")(tuple(0.0, 0.0), a); assert(approxEqual(r[0], 35)); // sum assert(approxEqual(r[1], 233)); // sum of squares // Compute average and standard deviation from the above auto avg = r[0] / a.length; auto stdev = sqrt(r[1] / a.length - avg * avg);