首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用boost::algorithm::join on tuple?

如何使用boost::algorithm::join on tuple?
EN

Stack Overflow用户
提问于 2012-12-22 08:09:36
回答 4查看 2K关注 0票数 3

boost::algorithm::joinstd::vector<std::string>上提供了一个方便的连接。

在进行连接之前,如何扩展此功能以使用std::vector<std::tuple<std::string,bool>>将结果包围为单引号(用于字符串)(如果为true )。

这对于循环来说并不难,但我正在寻找一种解决方案,最大限度地利用了标准算法和C++11特性(例如lambdas)。

继续使用boost的连接,如果可行的话:elegance/readability/conciseness更重要。

代码语言:javascript
复制
#include <string>
#include <vector>
#include <tuple>
#include <boost/algorithm/string/join.hpp> 

int main( int argc, char* argv[] )
{
  std::vector<std::string> fields = { "foo", "bar", "baz" };
  auto simple_case = boost::algorithm::join( fields, "|" );

  // TODO join surrounded by single-quotes if std::get<1>()==true
  std::vector<std::tuple< std::string, bool >> tuples =
   { { "42", false }, { "foo", true }, { "3.14159", false } };

  // 42|'foo'|3.14159 is our goal
}

编辑

好的,下面我采纳了kassak的建议,并看了一下boost::transform_iterator() --boost自己的文档中这个例子的冗长让我望而却步,所以我尝试了std::transform() --它没有我想要的那么短,但它似乎很有效。

答案

代码语言:javascript
复制
#include <string>
#include <vector>
#include <tuple>
#include <iostream>
#include <algorithm>
#include <boost/algorithm/string/join.hpp> 

static std::string
quoted_join( 
    const std::vector<std::tuple< std::string, bool >>& tuples, 
    const std::string& join
)
{
    std::vector< std::string >  quoted;
    quoted.resize( tuples.size() );
    std::transform( tuples.begin(), tuples.end(), quoted.begin(),
        []( std::tuple< std::string, bool > const& t ) 
        {
            return std::get<1>( t ) ? 
                "'" + std::get<0>(t) + "'" :
                std::get<0>(t);
        }
    );
  return boost::algorithm::join( quoted, join );
}

int main( int argc, char* argv[] )
{
  std::vector<std::tuple< std::string, bool >> tuples =
  { 
    std::make_tuple( "42", false ), 
    std::make_tuple( "foo", true ), 
    std::make_tuple( "3.14159", false ) 
  };

  std::cerr << quoted_join( tuples, "|" ) << std::endl;
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-12-22 08:23:54

如果要使用联接,可以在boost::transform_iterator中包装集合,并在需要时添加引号。

票数 1
EN

Stack Overflow用户

发布于 2012-12-22 12:50:41

首先编写make_transform_range( old_range, functor )。对于第一个版本,假设old_range是迭代器的std::pair,但理想情况下,它应该是允许begin(c)的任何东西。

然后答案变得非常干净和高效。取您正在处理的范围,在不实际调用函数的情况下对其进行转换,然后调用联接。

在我的电话里,所以输入一个毛茸茸的make_transform_range是我无法想象的。而且很有毛。

下面是一个不那么抽象的尝试。

代码语言:javascript
复制
auto functor = []( my_pair const&p )->std::string {
  if (p.second) return quote( p.first );
  return p.first;
};
auto tbegin = boost::make_transform_iterator( b, functor );
auto tend = boost::make_transform_iterator( e, functor );
join(…);

如果...which有效的话,它不像我所担心的那么恶劣。我仍然认为make_transform_range是值得的,但可能不是一次性的。

另一种方法是boost range库,包含所有这些古怪的语法。它已经进行了基于范围的变换。

票数 3
EN

Stack Overflow用户

发布于 2012-12-26 03:30:34

使用Boost.Rangetransformed适配器是最简单的:

代码语言:javascript
复制
#include <string>
#include <vector>
#include <tuple>
#include <iostream>
#include <algorithm>
#include <boost/algorithm/string/join.hpp> 
#include <boost/range/adaptor/transformed.hpp>

int main()
{
    std::vector<std::tuple< std::string, bool >> tuples =
    { 
        std::make_tuple( "42", false ), 
        std::make_tuple( "foo", true ), 
        std::make_tuple( "3.14159", false ) 
    };

  std::cout
      << boost::algorithm::join( 
                tuples | boost::adaptors::transformed(
                    [](std::tuple< std::string, bool > const &tup){
                        return std::get<1>(tup) ? 
                            "'" + std::get<0>(tup) + "'" :
                                  std::get<0>(tup);
                    }
                ), "|" )
      << std::endl;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14001160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档