C++ tools with the same functionality as Python's filter and map
boost, c++, functional-programming, python
Solution
As @juanchopanza has suggested, the template functions in the `<algorithm>` STL header are your best bet.
#include <iostream>
#include <vector>
std::vector<std::string> filter(std::vector<std::string> & raw) {
std::vector<std::string> result(raw.size());
std::string last = raw[raw.size() - 1];
auto it = std::copy_if(raw.begin(), raw.end(), result.begin(),
[&](std::string s) { return s.compare(last) > 0; });
result.resize(std::distance(result.begin(), it));
return result;
}
int main(int argc, const char *argv[])
{
std::vector<std::string> raw, result;
std::string input;
while (std::getline(std::cin, input)) {
raw.push_back(input);
}
result = filter(raw);
for (size_t i = 0; i < result.size(); i++) {
std::cout << "Matched: " << result[i] << std::endl;
}
std::cout << "Results: " << result.size() << std::endl;
return 0;
}
Compile and run:
$ clang++ -std=c++11 -o cppfilter main.cpp && ./cppfilter
121
123
122
120 // Ctrl + D pressed
Matched: 121
Matched: 123
Matched: 122
Results: 3
Problem
I am looking for a C++ analogs for a `map` or `filter` from Python programming language. The first of them applies some function to every item of iterable and return a list of the results, the second constructs a list from those elements of iterable for which function returns true. I would like to use the similar functionality in C++: - Map some function to the container in order to get new container with a transformed data (and probably with a different length); - Use some kind of conditional filtering for a container; Are there any fine implementations of Python's map and filter in C++? In this short example I am trying to work it out using such tools as `boost::bind` and `std::for_each` and I face with a difficulties. The `std::vector<std::string> result` should contain all the strings `std::vector<std::string> raw` that lexicographicaly higher than the last string from stdin. But in fact the `result` container is still empty at the return point. ``` #include <iostream> #include <vector> #include <algorithm> #include <boost/bind.hpp> void filter_strings(std::string& current, std::string& last, std::vector<std::string>& results) { if (current > last) { results.push_back(current); std::cout << "Matched: " << current << std::endl; } } int main() { std::vector<std::string> raw, result; std::string input, last; //Populate first container with a data while(std::getline(std::cin, input)) raw.push_back(input); last = raw.back(); //Put into result vector all strings which lexicographically higher than the last one std::for_each(raw.begin(), raw.end(), boost::bind(&filter_strings, _1, last, result)); //For some reason the resulting container is empty std::cout << "Results: " << result.size() << std::endl; return 0; } ``` The input and the output: ``` [vitaly@thermaltake 1]$ ./9_boost_bind 121 123 122 120 //Ctrl+D key press Matched: 121 Matched: 123 Matched: 122 Results: 0 ``` Any help will be appreciated.