The Simple Functional Template Library
[[reduce]]
 

reduce

Definition

X reduce( C<X> container, F<X> functor );
Y reduce( C<X> container, F<X,Y> functor, Y initial_value );

where :

  • C is a container type (template)
  • F is the functor type (template)
  • X is the type of objects in the input container
  • Y is the functor result type (second signature only)

Parameters

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

Return value

  • An object of type X for the first signature
  • An object of type Y for the second signature

Description

reduce calls the functor for each element of the container, giving as arguments :

  • the result of the last call to the functor (or the first element/initial value if there hasn't been any)
  • the next element in the container

The returned value is the result of the last call to the functor.


reduce can be used in two ways :

1. using the first signature

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).

Example

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 )

2. using the second signature

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).

Example

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 )

Examples

#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
}
 
reduce.txt · Last modified: 2007/08/24 23:31 (external edit)
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki