27
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rustでfor文を使わないでRangeとかVecとかスライスを処理する方法

Last updated at Posted at 2018-04-26

※2018年6月21更新:Rust 1.26以降(Inclusive rangeを使用)

はじめに

forとか書かなくていいなら書かないほうがよくない??????

もちろん、書いたほうが読みやすいぜ!
みたいなところもあるけど。

でも、例えば1~100の数字に対してすべて2倍するとか、奇数だけ取り出して二乗するとか
fizzbuzzするとかそういうことするだけだったら、ぶっちゃけfor文いらないよね。

以下の例では、Vecを例に使っているけど、スライスも
Iteratorトレイトを実装しているので、まったく同じコードで書ける。

for文を使わずに、奇数を2乗

fn main(){
    let n = (0..=20).collect::<Vec<u32>>();
    
    let v = n.iter().filter(|n|(*n)%2==1).map(|n|n*n).collect::<Vec<u32>>();
    println!("{:?}",v);
}

ちょースマート

もっとスマートに(追記)

fn main(){
    println!("{:?}",(0..=20).filter(|n|(*n)%2==1).map(|n| n * n).collect::<Vec<u32>>());
}

もっともっとスマートに(追の追記)

@tatsuya6502 さんからめっちゃ良いアドバイスをもらったので追記
ありがとうございます

fn main() {
    (0..=20)
        .filter_map(|n| if n % 2 == 1 { Some(n * n) } else { None })
        .for_each(|n| print!("{}, ", n));
    println!("");
}

filter_mapで条件と実行内容を合わせて書けるの良いし
for_eachでprintできるから自分で成型する場合もすごく見やすくなった。

めっちゃPythonっぽい。

for文使わずにFizzbuzzする

fn main(){
    let n = (0..=20).collect::<Vec<u32>>();

    let fb = n.iter().map(fizzbuzz).collect::<Vec<String>>();
    println!("{:?}",fb);
}

fn fizzbuzz(n:&u32)->String{
    match n{
        n if n%3==0&&n%5==0 =>"fizz buzz".to_owned(),
        n if n%3==0 =>"fizz".to_owned(),
        n if n%5==0 =>"buzz".to_owned(),
        n => n.to_string()
    }
}

最の高

もっとスマートに(追記)

fn main(){
    println!("{:?}",(0..=20).map(fizzbuzz).collect::<Vec<String>>());
}

fn fizzbuzz(n:u32)->String{
    match n{
        n if n%3==0&&n%5==0 =>"fizz buzz".to_owned(),
        n if n%3==0 =>"fizz".to_owned(),
        n if n%5==0 =>"buzz".to_owned(),
        n => n.to_string()
    }
}

もっともっとスマートに(追の追記)

fn main() {
    (1..=20).map(fizzbuzz).for_each(|n| print!("{}, ", n));
    println!("");
}

fn fizzbuzz(n:u32)->String{
    match n{
        n if n%15==0 =>"fizz buzz".to_owned(),
        n if n%3==0 =>"fizz".to_owned(),
        n if n%5==0 =>"buzz".to_owned(),
        n => n.to_string()
    }
}

どんなコードが実際吐かれるかは書かれてるかは逆アセ見てみればわかるけど
たぶんVecの処理がなくなったからヒープのアロケートとコピーが減ったりで
早くなってるかもしれない

おわりに

Rustはいいぞ。

27
16
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?