【Rust】iter(), into_iter()を使って、JR東日本のどこかにビューーン!をRustで実装する!

ここでは東北、秋田、山形新幹線の駅からそれぞれ一つづつランダムに駅を抽出する組み合わせを出力するという簡易的な実装例とする。
実際のどこかにビューーン!は、更に上越、北陸新幹線もあり、候補47駅、5つの新幹線の中から4つの駅を出力しているので、若干ロジックが異なるが、考え方はおおよそ同じだ。※[東北、秋田、山形、上越、北陸]から、4つをランダムに抽出して、そこから更にランダムに抽出しているのかもしれない。

サーバ側では、各駅がどの新幹線駅かというデータを持っておき、iteratorからfilterでそれぞれの新幹線ごとにvectorに入れて、そこからランダムに抽出する。下のサンプルでは、最後に往復料金でソートしてprintln!している。

use rand::prelude::IndexedRandom;

#[derive(Debug, Clone)]
struct Destination {
    bullet_train: String,
    station: String,
    ticket_price: u32
}

fn main() {
    let data = [
        Destination{ bullet_train: "東北".to_string(), station: "那須塩原".to_string(), ticket_price: 12040},
        Destination{ bullet_train: "東北".to_string(), station: "新白河".to_string(), ticket_price: 13580},
        Destination{ bullet_train: "東北".to_string(), station: "郡山".to_string(), ticket_price: 16680},
        Destination{ bullet_train: "東北".to_string(), station: "福島".to_string(), ticket_price: 18220},
        Destination{ bullet_train: "東北".to_string(), station: "白石蔵王".to_string(), ticket_price: 21080},
        Destination{ bullet_train: "東北".to_string(), station: "仙台".to_string(), ticket_price: 22180},
        Destination{ bullet_train: "東北".to_string(), station: "古川".to_string(), ticket_price: 23280},
        Destination{ bullet_train: "秋田".to_string(), station: "雫石".to_string(), ticket_price: 32200},
        Destination{ bullet_train: "秋田".to_string(), station: "田沢湖".to_string(), ticket_price: 32640},
        Destination{ bullet_train: "秋田".to_string(), station: "角館".to_string(), ticket_price: 34040},
        Destination{ bullet_train: "秋田".to_string(), station: "大曲".to_string(), ticket_price: 34700},
        Destination{ bullet_train: "秋田".to_string(), station: "秋田".to_string(), ticket_price: 36040},
        Destination{ bullet_train: "山形".to_string(), station: "米沢".to_string(), ticket_price: 21060},
        Destination{ bullet_train: "山形".to_string(), station: "高畠".to_string(), ticket_price: 21500},
        Destination{ bullet_train: "山形".to_string(), station: "赤湯".to_string(), ticket_price: 22240},
        Destination{ bullet_train: "山形".to_string(), station: "かみのやま温泉".to_string(), ticket_price: 22900},
        Destination{ bullet_train: "山形".to_string(), station: "さくらんぼ東根".to_string(), ticket_price: 24900},
        Destination{ bullet_train: "山形".to_string(), station: "村山".to_string(), ticket_price: 24900},
        Destination{ bullet_train: "山形".to_string(), station: "大石田".to_string(), ticket_price: 24900},
        Destination{ bullet_train: "山形".to_string(), station: "新庄".to_string(), ticket_price: 26000},
    ];

    let mut JR_Voom = Vec::new();

    let tohoku: Vec<Destination> = data.clone().into_iter()
        .filter(|d|d.bullet_train == "東北")
        .collect();
    JR_Voom.push(tohoku.choose(&mut rand::thread_rng()).unwrap());

    let akita: Vec<Destination> = data.clone().into_iter()
        .filter(|d|d.bullet_train == "秋田")
        .collect();
    JR_Voom.push(akita.choose(&mut rand::thread_rng()).unwrap());

    let yamagata: Vec<Destination> = data.clone().into_iter()
        .filter(|d|d.bullet_train == "山形")
        .collect();
    JR_Voom.push(yamagata.choose(&mut rand::thread_rng()).unwrap());
    JR_Voom.sort_by(|a, b| a.ticket_price.cmp(&b.ticket_price));

    for (i, destination) in JR_Voom.iter().enumerate() {
        println!("{:}: {}駅 (往復{}円)", i + 1, destination.station, destination.ticket_price);
    }
    
}

何度か実行すると以下のようになる。うん、見たことある光景である。
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.55s
Running `target/debug/app`
1: 郡山駅 (往復16680円)
2: 新庄駅 (往復26000円)
3: 秋田駅 (往復36040円)

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.08s
Running `target/debug/app`
1: 米沢駅 (往復21060円)
2: 古川駅 (往復23280円)
3: 雫石駅 (往復32200円)

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.16s
Running `target/debug/app`
1: 福島駅 (往復18220円)
2: 米沢駅 (往復21060円)
3: 田沢湖駅 (往復32640円)

プログラムでランダムに抽出しているだけだが、これに一喜一憂しているのだからしょうがない。多分、●●駅の方が△△駅よりも出やすくするといった駅によっての重み付とかはないと思うが、実際のところは分かりません。。