【问题标题】:How do I copy the strings in a vector<pair<string, int>> to vector<string>?如何将 vector<pair<string, int>> 中的字符串复制到 vector<string>?
【发布时间】:2021-04-23 21:19:33
【问题描述】:

我使用的是 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 > >() );

【问题讨论】:

  • 应该是范围的主要示例。

标签: c++ vector boost transform push-back


【解决方案1】:

继续发布最小改进的趋势:

Live On Compiler Explorer

#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}

【讨论】:

  • 完美,map_keys 适配器正是我想要的!!!
【解决方案2】:

您可以将 std::transformstd::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;
               });

【讨论】:

  • 好的,谢谢。我只想知道是否可以“简化”这条线以使用提升算法
  • @AlexandrDerkach 我不能 100% 确定,但这可能是已进入标准的增强算法之一。
  • @AlexandrDerkach,看看my answer
  • 我真的需要开始学习这些范围的东西......看起来不错。
  • @TedLyngmo,关于范围从Functional Programming in C++ 的章节是免费的,iIcr。
【解决方案3】:

这是一个使用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);
}

【讨论】:

  • @TedLyngmo, dest 是一个视图。你可以通过boost::copy_range 得到一个实际的向量。请看我的变化。
  • 不错。 std::vector&lt;std::string&gt; dest_vec(dest.begin(), dest.end()); 似乎也有效。你得到了我的投票:-)
  • @TedLyngmo,你也有我的。
  • Boost 比这更方便! godbolt.org/z/o5Wh7o (/cc @TedLyngmo 选择post as another contender
  • @sehe Briliant!我并不经常投票赞成一个问题,提供一个答案并赞成所有其他答案 :-) 我从你们那里学到了很多。
【解决方案4】:

这是使用 range-v3 库的解决方案:

auto dest = source 
          | ranges::views::keys 
          | ranges::to<std::vector<std::string>>;

这是demo


在 C++20 中,没有 std::ranges::to,但您仍然可以将密钥复制到 dest(如果它已经存在):

std::ranges::copy(source | std::views::keys, 
                  std::back_inserter(dest));

这是demo

请注意,这在 Clang 主干中不起作用,我认为这是一个错误。

【讨论】:

  • 又一个不错的——这里是my C++20 attempt——虽然我找不到ranges::to的标准版本,但我也尝试使用&lt;format&gt;中的fmt::print,但似乎两者都不是g++ clang++ 也没有 &lt;format&gt; 标头。
  • @TedLyngmo Nice :) 是的,还没有人实现&lt;format&gt;。我实际上想发布一个使用std::ranges::copy 填充dest 的解决方案,但无法使其正常工作。我本来想写一个关于它的问题,但走题了。感谢您的评论,它提醒了我 :) 顺便说一句,std::viewsstd::ranges::views 的简写,所以少了几个字符。
  • 不客气 :-) 我找到了为什么我找不到 ranges::to:A Plan for C++23 Ranges - P2214r0 - View adjuncts:“缺少功能的一个关键部分是 ranges::to[P1206R1]。 "
  • @TedLyngmo 嗯,它在 GCC 中确实有效,但在 Clang 中无效。我认为这是一个 Clang 错误,所以我也更新了一个包含 C++20 范围的解决方案。
  • @TedLyngmo 哦,是的,当to 没有进入 C++20 时,我感到非常失望 :( 但我想我们不能同时拥有所有的好东西 :p
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-11
  • 1970-01-01
相关资源
最近更新 更多