[英]How do I copy the strings in a vector<pair<string, int>> to vector<string>?
I'm using GCC 9.2.0 and boost 1.55.我正在使用 GCC 9.2.0 和提升 1.55。
I have 2 vectors:我有 2 个向量:
vector< pair< string, int > > source;
vector< string > dest;
I need to transform the source
vector to the dest
, such that it should contain only string
elements of source
vector.我需要将
source
向量转换为dest
,这样它应该只包含source
向量的string
元素。
Is it possible using boost::push_back
and adaptors?是否可以使用
boost::push_back
和适配器?
boost::range::push_back( dest, source | /* adaptor ??? */ );
Currently I have this workable code, but it should be changed:目前我有这个可行的代码,但应该改变它:
transform( source.begin(), source.end(), back_inserter(dest), __gnu_cxx::select1st< std::pair< std::string, int > >() );
To continue the trend of posting mimimal improvements:要继续发布最小改进的趋势:
Live On Compiler Explorer Live On 编译器资源管理器
#include <boost/range/adaptor/map.hpp>
#include <fmt/ranges.h>
using namespace std::string_literals;
using namespace boost::adaptors;
template <typename R>
auto to_vector(R const& range) {
return std::vector(boost::begin(range), boost::end(range));
}
int main() {
std::vector source {std::pair {"one"s,1},{"two",2},{"three",3}};
fmt::print("keys {}\nvalues {}\n",
source | map_keys,
source | map_values);
// if you really need the vectors
auto keys = to_vector(source | map_keys);
auto values = to_vector(source | map_values);
}
Prints印刷
keys {"one", "two", "three"}
values {1, 2, 3}
You could use std::transform
and std::back_inserter
with a lambda instead:您可以将
std::transform
和std::back_inserter
与 lambda 一起使用:
#include <algorithm> // transform
#include <iterator> // back_inserter
std::transform(source.begin(), source.end(), std::back_inserter(dest),
[](auto& p) {
return p.first;
});
Here's a boost solution with the transformed
adaptor:这是使用
transformed
后的适配器的升压解决方案:
#include <boost/range/adaptor/transformed.hpp>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
using boost::adaptors::transformed;
// define function object (so we can pass it around) emulating std::get
template<std::size_t N>
auto constexpr get = [](auto const& x){ return std::get<N>(x); };
int main()
{
// prepare sample input
std::vector<std::pair<std::string,int>> source{{"one",1},{"two",2},{"three",3}};
// the line you look for
auto dest = source | transformed(get<0>);
// dest is a vector on which we can iterate
for (auto const& i : dest) {
std::cout << i << '\n';
}
// if you really need it to be a vector
auto dest_vec = boost::copy_range<std::vector<std::string>>(dest);
}
Here's a solution using the range-v3 library:这是使用 range-v3 库的解决方案:
auto dest = source
| ranges::views::keys
| ranges::to<std::vector<std::string>>;
In C++20, there's no std::ranges::to
, but you can still copy over the keys to dest
if it already exists:在 C++20 中,没有
std::ranges::to
,但如果它已经存在,您仍然可以将键复制到dest
:
std::ranges::copy(source | std::views::keys,
std::back_inserter(dest));
Note that this doesn't work in Clang trunk, which I assume is a bug.请注意,这在 Clang 主干中不起作用,我认为这是一个错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.