map<T,Z> m= ...;
vector<T> v;
v.reserve(m.size);
for(map<T,Z>::iterator it=m.begin();it!=m.end();++it)
{
v.push_back(it->first);
}
Is there a nicer 1-line version using some STL function(s)?
edit: not using c++11!
Portable:
struct SelectKey {
template <typename F, typename S>
F operator()(const std::pair<const F, S> &x) const { return x.first; }
};
std::transform(m.cbegin(), m.cend(), std::back_inserter(v), SelectKey());
I think some implementations of STL have a non-standard extension called select1st
, which is the equivalent of SelectKey
shown here. As K-Ballo pointed out in the comments, there's also a TR1 version. I like the explicitly-named version as it's easier to see what's going on.
Since there's no need for state, you can get away with slightly less boilerplate by using an actual function rather than a functor:
template <typename F, typename S>
F SelectKey()(const std::pair<const F, S> &x) { return x.first; }
std::transform(m.cbegin(), m.cend(), std::back_inserter(v), SelectKey);
If you could use C++11, you could use a lambda, which keeps the selection code close to where it's used:
std::transform(m.cbegin(), m.cend(), std::back_inserter(v),
[](const std::pair<const F, S> &x) { return x.first; });
or even range-based for-loop, which is probably the most elegant and readable:
for(const auto &x : m) {
v.push_back(x.first);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With