X reduce( C<X> container, F<X> functor ); Y reduce( C<X> container, F<X,Y> functor, Y initial_value );
where :
Parameter | Description |
---|---|
container | an STL container of type C holding objects type X |
functor | a function taking two parameters of type X and returning a value of type X OR a functor taking a parameter of type Y and a parameter of type X and returning a value of type Y |
reduce
calls the functor for each element of the container, giving as arguments :
The returned value is the result of the last call to the functor.
reduce
can be used in two ways :
This is when the functor returns a value of the same type as its parameters (the functor takes two parameters of type X and returns a value of type X).
In that case reduce
initiates the process by first calling the functor with the two first elements of the container. It then continues by iteratively calling the functor with the value returned by the last call to the functor and the next element (starting at the third element).
The sum
function (see below) takes two int
parameters and returns an int
.
the iteration goes as follow :
<result_a> = sum( 1, 2 ) // the functor is first applied to the first two elements <result_b> = sum( <result_a>, 3 ) // from there, the functor applied to the last result and the next element <result_c> = sum( <result_b>, 4 ) ... <final_result> = sum( <result_g>, 9 )
This is when the functor doesn't return a value of the same type as its parameters (the functor takes one parameter of type X and one parameter of type Y and returns a value of type Y).
In that case reduce
expects an initial value as parameter. The process is initiated by calling the functor with the initial value and the first element of the container. It then continues by iteratively calling the functor with the value returned by the last call to the functor and the next element (starting at the second element).
The avg
function (see below) takes an Accumulator
and an int
as parameters and returns an Accumulator
the iteration goes as follow :
<result_a> = avg( <initial_value>, 1 ) // functor is first applied to the initial value and the first element <result_b> = avg( <result_a>, 2 ) // from there, the functor is applied to the last result and the next element <result_c> = sum( <result_b>, 3 ) ... <final_result> = sum( <result_h>, 9 )
#include <iostream> #include <vector> #include <sstream> #include "sftl.h" using namespace std; // function that returns the sum of two ints int sum( int x, int y ) { return x+y; } // function that concatenates the string s with the integer x (as string) string join( string s, int x ) { stringstream stream; stream << s << x << " "; return stream.str(); } // structure with count and sum fields struct Accumulator { int count; int sum; Accumulator() : count(0), sum(0) {} Accumulator( int count, int sum ) : count(count), sum(sum) {} double get() { return (double)sum/(double)count; } }; // functor that updates the Accumulator with the given integer Accumulator average( Accumulator acc, int x ) { return Accumulator( acc.count+1, acc.sum+x ); } int main() { // create vector of numbers int numbers [] = {1,2,3,4,5,6,7,8,9}; vector<int> v_numbers( &numbers[0], &numbers[9] ); // example 1 : build a string from elements string str = reduce( v_numbers, join, string() ); cout << "numbers : " << str << endl; // prints 1 2 3 ... 9 // example 2 : compute the sum of elements int total = reduce( v_numbers, sum ); cout << "sum : " << total << endl; // prints 45 // example 3 : compute the average of elements double avg = reduce( v_numbers, average, Accumulator() ).get(); cout << "average : " << avg << endl; // prints 5 }