polapts polapts - 2 months ago 22
C++ Question

boost::range to process content of a container and pipe to next process with values from a map

I have a map like

std::map<std::string, std::vector<int> >
. I want to create one vector out of all the sub-vectors from values of the map. I can do it using the loops but I wanted to use the
boost::range
library where I can pipe the input of one transform to another so that the code is more readable and succinct. I tried something like below but needed some help to do it correctly.
Thank you

#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm/copy.hpp>
#include <iterator>
#include <vector>
#include <map>
#include <iostream>

struct GetMapValue
{
template<typename T1, typename T2>
const T2& operator()( const std::pair<T1,T2>& key_val ) const
{
return key_val.second;
}
};

struct GetINTs
{
GetINTs(std::vector<int> aVec1)
{
aMyVec = aVec1;
}
void operator()( const std::vector<int>& val )
{
aMyVec.insert( val.end(), val.begin(), aMyVec.end() );
}
private:
std::vector<int> aMyVec;

};

int main(){

std::map<std::string, std::vector<int> > x;
std::vector<int> y, z;

std::vector<int> temp;
temp.push_back(1);
temp.push_back(1);
x.insert(std::make_pair("one", temp));

temp.clear();
temp.push_back(2);
temp.push_back(2);
x.insert(std::make_pair("two", temp));

temp.clear();
temp.push_back(3);
temp.push_back(3);
x.insert(std::make_pair("three", temp));

boost::copy( x | boost::adaptors::transformed(GetMapValue), std::back_inserter(y) );
boost::copy( y | boost::adaptors::transformed(GetINTs), std::back_inserter(z) );

}

Answer

The adaptor already exists and is called

Here's a sample:

Live On Coliru

#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>
#include <map>

int main() {
    std::map<std::string, std::vector<int> > x {
        { "hello", { 1,2,3 } },
        { "world", { 4,5,6 } },
    };

    boost::copy(x | boost::adaptors::map_keys, std::ostream_iterator<std::string>(std::cout << "Keys: ", " "));
    for (auto& vec : x | boost::adaptors::map_values)
        boost::copy(vec, std::ostream_iterator<int>(std::cout << "\nValues: ", " "));
}

Prints

Keys: hello world 
Values: 1 2 3 
Values: 4 5 6