Created
December 1, 2017 23:41
-
-
Save dragon0/bc6f0f976ec95b8c09d9e51f08c4c30a to your computer and use it in GitHub Desktop.
Using sequence operations (map/filter/reduce) in C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> // cout | |
#include <algorithm> // transform | |
#include <vector> // vector | |
using namespace std; | |
void print (int i) { cout << ' ' << i; } | |
struct c_unique { | |
int current; | |
// constructor | |
c_unique() { | |
current=0; // ensure current starts at 0 | |
} | |
int operator()() { | |
return ++current; // increment current and return the new value | |
} | |
} UniqueNumber; | |
int op_increase (int i) { return i+1; } | |
void transform_example () { | |
vector<int> nums; | |
vector<int> result; | |
// set some values: | |
nums.resize(5); // We want 5 values | |
generate(nums.begin(), nums.end(), UniqueNumber); | |
// nums: 1 2 3 4 5 | |
// Inputs are all memory locations between nums.begin() and nums.end() | |
// Results are stored in succesive memory locations starting at | |
// result.begin(), which is why result must be resized before the call. | |
result.resize(nums.size()); | |
transform (nums.begin(), nums.end(), result.begin(), op_increase); | |
// result: 2 3 4 5 6 | |
cout << "transform:"; | |
for_each(result.begin(), result.end(), print); | |
cout << endl; | |
} | |
bool is_positive(int i) { return !(i<0); } | |
void copy_if_example () { | |
vector<int> nums = {25,15,-5,-15,5}; | |
vector<int> result (nums.size()); // passing initial size to constructor | |
// We don't know exactly how many results there will be, | |
// but there can't possibly be more than nums.size(). | |
auto it = copy_if (nums.begin(), nums.end(), result.begin(), is_positive); | |
// Not all values will be copied. copy_if returns the location where the | |
// last value was copied. distance can be used to determine how many values | |
// were copied, and resize can be used to shrink result to that size. | |
result.resize(distance(result.begin(),it)); | |
// result: 25 15 5 | |
cout << "copy_if:"; | |
for_each(result.begin(), result.end(), print); | |
cout << endl; | |
} | |
int myfunction (int acc, int num) {return acc+2*num;} | |
void accumulate_example () { | |
int init = 100; | |
// The sequence functions can also be used with arrays | |
int numbers[] = {10,20,30}; | |
// Inputs are all memory locations from numbers to numbers+3 | |
int result = accumulate (numbers, numbers+3, init, myfunction); | |
// result: 220 | |
cout << "accumulate: " << result << endl; | |
} | |
int main() { | |
transform_example(); | |
copy_if_example(); | |
accumulate_example(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment