如何将 vector<pair<string, int>> 中的字符串复制到 vector<string>?
How do I copy the strings in a vector<pair<string, int>> to vector<string>?
我正在使用 GCC 9.2.0 和 boost 1.55。
我有 2 个向量:
vector< pair< string, int > > source;
vector< string > dest;
我需要将 source
向量转换为 dest
,这样它应该只包含 source
向量的 string
个元素。
是否可以使用 boost::push_back
和适配器?
boost::range::push_back( dest, source | /* adaptor ??? */ );
目前我有这个可用的代码,但应该更改它:
transform( source.begin(), source.end(), back_inserter(dest), __gnu_cxx::select1st< std::pair< std::string, int > >() );
您可以将 std::transform
and 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;
});
这是使用 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);
}
继续发布最小改进的趋势:
#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);
}
版画
keys {"one", "two", "three"}
values {1, 2, 3}
这是一个使用 range-v3 库的解决方案:
auto dest = source
| ranges::views::keys
| ranges::to<std::vector<std::string>>;
这是 demo。
在 C++20 中,没有 std::ranges::to
,但如果 dest
已经存在,您仍然可以将其复制到 dest
:
std::ranges::copy(source | std::views::keys,
std::back_inserter(dest));
这里是 demo。
请注意,这在 Clang 主干中不起作用,我认为这是一个错误。
我正在使用 GCC 9.2.0 和 boost 1.55。
我有 2 个向量:
vector< pair< string, int > > source;
vector< string > dest;
我需要将 source
向量转换为 dest
,这样它应该只包含 source
向量的 string
个元素。
是否可以使用 boost::push_back
和适配器?
boost::range::push_back( dest, source | /* adaptor ??? */ );
目前我有这个可用的代码,但应该更改它:
transform( source.begin(), source.end(), back_inserter(dest), __gnu_cxx::select1st< std::pair< std::string, int > >() );
您可以将 std::transform
and 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;
});
这是使用 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);
}
继续发布最小改进的趋势:
#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);
}
版画
keys {"one", "two", "three"}
values {1, 2, 3}
这是一个使用 range-v3 库的解决方案:
auto dest = source
| ranges::views::keys
| ranges::to<std::vector<std::string>>;
这是 demo。
在 C++20 中,没有 std::ranges::to
,但如果 dest
已经存在,您仍然可以将其复制到 dest
:
std::ranges::copy(source | std::views::keys,
std::back_inserter(dest));
这里是 demo。
请注意,这在 Clang 主干中不起作用,我认为这是一个错误。