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.

Original source