rs.nkmk.me

Rustで文字列のベクタVec<String>を連結(concat, join)

Posted: | Tags: Rust, 文字列, ベクタ

Rustで文字列のベクタVec<String>などを一つの文字列Stringに連結(結合)するには、concatまたはjoinメソッドを使う。新たな文字列Stringが生成される。

なお、concatjoinは複数のVecを一つのVecに連結するのにも使われる。

複数の文字列Stringや文字列スライス&strを連結する方法については以下の記事を参照。

以下のサンプルコードでは、説明のため、型推論によって省略できるときも明示的に型注釈を記述している場合がある。

Vec<String>などを連結: concat

concatはスライスのメソッド。

型強制によってVecや配列からも呼べる。

Vec<String>Stringに連結する例。

let v: Vec<String> = vec![
    String::from("aaa"),
    String::from("bbb"),
    String::from("ccc"),
];
let s: String = v.concat();
assert_eq!(s, "aaabbbccc");

スライスから呼ぶ例。

let s: String = v[1..].concat();
assert_eq!(s, "bbbccc");

要素は文字列スライス&strでもよい。以下は配列[&str; N]を連結する例。返り値は常に文字列String

let a: [&str; 3] = ["aaa", "bbb", "ccc"];
let s: String = a.concat();
assert_eq!(s, "aaabbbccc");

例は省略するが、Vec<&str>[String; N]でも同じ。

セパレータを挿入して連結: join

joinもスライスのメソッド。

引数に指定した文字列スライス&strがセパレータとして間に挿入される。

let v: Vec<String> = vec![
    String::from("aaa"),
    String::from("bbb"),
    String::from("ccc"),
];
let s: String = v.join("-");
assert_eq!(s, "aaa-bbb-ccc");

文字列Stringをセパレータに指定する場合は参照を渡す。

let sep = String::from("+");
let s: String = v.join(&sep);
assert_eq!(s, "aaa+bbb+ccc");

要素は文字列スライス&strでもよい。以下は配列[&str; N]を連結する例。返り値は常に文字列String

let a: [&str; 3] = ["aaa", "bbb", "ccc"];
let s: String = a.join("-");
assert_eq!(s, "aaa-bbb-ccc");

例は省略するが、Vec<&str>[String; N]でも同じ。

文字列のイテレータを連結

例えばVecの要素の文字列を処理してから連結したい場合、iter().map()で生成されるイテレータを文字列に連結する必要がある。

collectでVecに変換してからconcat, join

一旦collectVec<String>に変換してしまえば、あとはこれまでの例のようにconcatjoinで連結できる。

let v: Vec<String> = vec![
    String::from("aaa"),
    String::from("bbb"),
    String::from("ccc"),
];

let s: String = v
    .iter()
    .map(|s| s.to_uppercase())
    .collect::<Vec<String>>()
    .join("x");
assert_eq!(s, "AAAxBBBxCCC");

itertoolsのItertools::join

外部クレートのitertoolsを使う方法もある。

Itertoolsトレイトをインポートすると、イテレータからjoinメソッドが使えるようになる。

use itertools::Itertools;

let s = v.iter().map(|s| s.to_uppercase()).join("x");
assert_eq!(s, "AAAxBBBxCCC");

concatメソッドも提供されているが、文字列を連結するものではない。

セパレータ無しで連結したい場合はjoin("")とすればよい。

let s = v.iter().map(|s| s.to_uppercase()).join("");
assert_eq!(s, "AAABBBCCC");

関連カテゴリー

関連記事