我想创建std::string
,其中包含std::map<std::string, std::string>
的第一个元素,它们被某个分隔符分隔(可以来自STL或Boost)。
有没有比循环更好的解决方案(一行)?就像boost::algorithm::join
的{{1}}一样。
答案 0 :(得分:4)
这可以使用Boost.Range的map_keys
和Boost.StringAlgo的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.hpp
答案 1 :(得分:1)
你的算法应该是这样的:
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;
}
基本上,您必须为地图中的每个元素循环并将其添加到字符串中。复杂度为 O(N),其中 N 是地图中元素的数量。
您可以提高在字符串结果上应用reserve
的算法的性能。
如果您知道字符串键的平均长度,则可以使用以下命令初始化变量:
std::string result;
result.reserve(map.size() * AVG_LENGTH_STR_KEY);
这将大大改善周期中的operator+=
操作。
答案 2 :(得分:1)
作为M.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
$
答案 3 :(得分:1)
如果您不想使用 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>
。