💬

Rustでfor文で文字列を探索する方法

2 min read 3

2021/8/22 追記
Keenさんさんにコメントでご指摘いただいた、Rustで推奨されている処理について追記しました。

Rustで文字列を1文字ずつ探索したい時に苦労したのでメモとして残します。

Rust Playground はこちら、GitHubはこちら

fn main() {
    let sentence :&str = "I love NewYork";
    //let sentence :String = "I love NewYork".to_string();

    for i in 0..sentence.len() as usize {
      println!("{}", sentence.chars().nth(i).unwrap());
    }
}

2021/8/22 追記

上記はRustで推奨されていない処理でした。
Keenさんさん、コメントでご指摘ありがとうございました!

\\ 1.推奨されている処理
for c in sentence.chars() {
  println!("{}", c);
}

\\ 2.推奨されていない処理
for i in 0..sentence.len() as usize {
  println!("{}", sentence.chars().nth(i).unwrap());
}

処理時間比較を比較してみました。

1.推奨処理 2.非推奨処理
0.230秒 0.335秒

検証したコード

chars()は文字列を文字に分割する

println!("{:?}", "I love NewYork".chars());

=> Chars(['I', ' ', 'l', 'o', 'v', 'e', ' ', 'N', 'e', 'w', 'Y', 'o', 'r', 'k'])

https://blog.kozakana.net/2021/01/get-characters-and-character-positions-with-chars/

nth()は n 文字目の文字を取得する

https://qiita.com/Linda_pp/items/d363ceff3c37bc9a4ae6

最後に .unwrap()を付ける

unwrap() は、 Option<T> 型や Result<T, E> 型の値(つまり、何かしらの値を ラップ している値)から中身の値を取り出す関数
https://ja.stackoverflow.com/questions/1730/rustのunwrapは何をするものですか

Discussion

こんにちは。

chars() の結果はイテレータを実装しているのでそのまま for 式で繰り返せます。

fn main() {
    let sentence :&str = "I love NewYork";
    //let sentence :String = "I love NewYork".to_string();

    for c in sentence.chars() {
      println!("{}", c);
    }
}

そのまま繰り返せるものをわざわざインデックスで取り出すのは回りくどいですし、 .chars().nth(i) は文字列の先頭から走査して遅いのでほぼ全ての場合で chars をそのまま繰り返す方が推奨されています。(参考: https://rust-lang.github.io/rust-clippy/master/#needless_range_loop

もしインデックスも同時に必要な処理をしているなら .enumerate() が使えます。

fn main() {
    let sentence :&str = "I love NewYork";
    //let sentence :String = "I love NewYork".to_string();

    for (i, c) in sentence.chars().enumerate() {
      println!("{}", c);
    }
}

記事中の参考リンクでも紹介されているやり方ですね。

参考になれば。

ログインするとコメントできます