vectorクラスで要素同士の結合を行う方法を紹介します(例: join({a, b}, ",") → "a,b"
)。
目次
vector同士の連結(例: {a, b} + {c, d} → {a, b, c, d}
)を行いたい場合には次のページを参考にして下さい。
>> std::vector同士の連結を行う方法【注意点と高速化】
要素の結合
ostream_iterator
クラスで結合処理を実現します。これで一般的なjoin関数の挙動を実現することが可能になります。
#include <string>
#include <vector>
#include <sstream>
int main() {
std::vector<std::string> v = {"a", "b", "c"};
std::ostringstream os;
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(os));
std::string s = os.str(); // "abc"
}
区切り文字を用いた文字列結合も可能です。末尾の区切り文字は手動で除去する必要があります。
std::vector<std::string> v = {"a", "b", "c"};
const char* delim = ","; // 区切り文字
// 結合
std::ostringstream os;
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(os, delim));
std::string s = os.str(); // "a,b,c,"
// 末尾区切り文字削除
s.erase(s.size() - std::char_traits<char>::length(delim));
s; // "a,b,c"
join関数の自作
join関数の自作も可能ですので参考にしてください。こちらはostream_iteratorを使わないバージョンです。また区切り文字を用いない結合にも対応しています。先程の方法よりも高速に動作します
join関数
std::string join(const std::vector<std::string>& v, const char* delim = 0) {
std::string s;
if (!v.empty()) {
s += v[0];
for (decltype(v.size()) i = 1, c = v.size(); i < c; ++i) {
if (delim) s += delim;
s += v[i];
}
}
return s;
}
使用例
std::vector<std::string> v = {"a", "b", "c"};
join(v); // "abc"
join(v, ""); // "abc"
join(v, "|"); // "a|b|c"
join(v, ", "); // "a, b, c"
join({}, ","); // ""
join({""}, ","); // ""
join({"a"}, ","); // "a"
join({"", ""}, ","); // ","
join({"", "", ""}, ","); // ",,"
join({"a", "b"}, ","); // "a,b"
番外編
back_inserterによる結合処理も可能です。以下はchar型要素を持つコンテナを文字列として連結する処理です。insertメソッドを活用する方法もあります。
std::string s = "a";
std::vector<char> v = {'b', 'c'};
std::copy(v.begin(), v.end(), std::back_inserter(s));
s; // "abc"
char d[] = {'d', 'e', 'f'};
std::copy(std::begin(d), std::end(d), std::back_inserter(s));
s; // "abcdef"
s.insert(s.end(), v.begin(), v.end());
s; // "abcdefbc"
なおback_inserterの挙動は、指定されたコンテナのpush_back
メソッドにコピー元の要素を渡すというものです。色々と応用できそうです。