我想创建一个std::string,它包含std::map<std::string, std::string>的第一个元素,用一些分隔符分隔(它可以来自STL或Boost)。有没有比循环更好的解决方案(一行)?就像boost::algorithm::join for std::vector<std::string>。
std::string
std::map<std::string, std::string>
boost::algorithm::join
std::vector<std::string>
5anewei61#
这可以通过使用Boost.Range的map_keys和Boost.StringAlgo的join来优雅地完成:
map_keys
join
std::string get_keys(const std::map<std::string, std::string>& map) { return boost::algorithm::join( map | boost::adaptors::map_keys, ", "); }
http://www.boost.org/doc/libs/1_61_0/boost/algorithm/string/join.hpphttp://www.boost.org/doc/libs/1_61_0/libs/range/doc/html/range/reference/adaptors/reference/map_keys.html
fwzugrvs2#
如果您不想使用 boost,请尝试std::accumulate:
const std::string delimiter = "#"; const std::string result = std::accumulate(M.begin(), M.end(), std::string(), [delimiter](const std::string& s, const std::pair<const std::string, std::string>& p) { return s + (s.empty() ? std::string() : delimiter) + p.first; });
在上面的代码中,M是一个std::map<std::string, std::string>。
M
92vpleto3#
你的算法应该是这样的:
std::string get_keys(const std::map<std::string, std::string>& map) { std::string result; std::for_each(map.cbegin(), map.cend(), [&result](const decltype(map)::value_type& p) { result += p.first; result += ", "; }); // Erase the last ", " from the string, if present if (result.size() > 0) { result.erase(result.size() - 2, 2); } return result; }
本质上,你必须循环查找map中的每个元素,并将其添加到字符串中,复杂度是 O(N),其中 N 是map中元素的数量。您可以提高对字符串结果应用reserve的算法的性能。如果您知道 string key 的平均长度,则可以使用以下命令初始化变量:
reserve
std::string result; result.reserve(map.size() * AVG_LENGTH_STR_KEY);
这将大大改善周期中的operator+=操作。
operator+=
wnrlj8wa4#
正如M.M.正确指出的那样,您可以为此使用boost::range(我添加了boost::string)。如果您的Map是m,则
boost::range
boost::string
m
std::vector<std::string> o; boost::copy(m | boost::adaptors::map_keys, std::back_inserter(o)); boost::algorithm::join(o, ", ");
(不幸的是,这需要大量的头文件。)
#include <boost/range/adaptor/map.hpp> #include <boost/range/algorithm/copy.hpp> #include <boost/assign.hpp> #include <boost/algorithm/string/join.hpp> #include <algorithm> #include <iostream> #include <map> #include <vector> int main() { std::map<std::string, std::string> m; m["hello"] = "world"; m["goodbye"] = "now"; std::vector<std::string> o; boost::copy(m | boost::adaptors::map_keys, std::back_inserter(o)); std::cout << boost::algorithm::join(o, ", ") << std::endl; }
此输出
$ ./a.out goodbye, hello $
ycggw6v25#
如果你正在使用一个json库,比如只有头文件的nlohmann::json你可以简单地尝试在一行中将它转换成一个json。注意:小心例外。
std::cout << "My map or vector: " << ((json)myMap)) << "\n";
编辑:我想这可能很懒,但它完成了工作,哈哈。
5条答案
按热度按时间5anewei61#
这可以通过使用Boost.Range的
map_keys
和Boost.StringAlgo的join
来优雅地完成:http://www.boost.org/doc/libs/1_61_0/boost/algorithm/string/join.hpp
http://www.boost.org/doc/libs/1_61_0/libs/range/doc/html/range/reference/adaptors/reference/map_keys.html
fwzugrvs2#
如果您不想使用 boost,请尝试std::accumulate:
在上面的代码中,
M
是一个std::map<std::string, std::string>
。92vpleto3#
你的算法应该是这样的:
本质上,你必须循环查找map中的每个元素,并将其添加到字符串中,复杂度是 O(N),其中 N 是map中元素的数量。
您可以提高对字符串结果应用
reserve
的算法的性能。如果您知道 string key 的平均长度,则可以使用以下命令初始化变量:
这将大大改善周期中的
operator+=
操作。wnrlj8wa4#
正如M.M.正确指出的那样,您可以为此使用
boost::range
(我添加了boost::string
)。如果您的Map是
m
,则(不幸的是,这需要大量的头文件。)
此输出
ycggw6v25#
如果你正在使用一个json库,比如只有头文件的nlohmann::json
你可以简单地尝试在一行中将它转换成一个json。注意:小心例外。
编辑:我想这可能很懒,但它完成了工作,哈哈。