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 }