I have a pretty simple flatmap
function implemented in C++ for std::vector
, but it has been suggested that ranges are generally better. Here's the vector based solution:
// flatmap: [A] -> (A->[B]) -> [B]
template<typename T, typename FN>
static auto flatmap(const std::vector<T> &vec, FN fn)
-> std::vector<typename std::remove_reference<decltype(fn(T())[0])>::type> {
std::vector<typename std::remove_reference<decltype(fn(T())[0])>::type> result;
for(auto x : vec) {
auto y = fn(x);
for( auto v : y ) {
result.push_back(v);
}
}
return result;
};
It has also been suggested that I use iterators, but that breaks the nice composability of the function:
map(filter(flatmap( V, fn), fn2), fn3)
I would assume that in a range-v3 world I'd be aiming for writing the above as:
auto result = v | flatmap(fn) | filter(fn2) | transform(fn3);
It feels like flatmap
should just be a trivial combination of views::for_each
, yield_from
and transform
, but I'm struggling to work out how to hook them all together.