Rustで構造体を含むVecをソートする

RustのHashMapで以下のようなコードを書いたとき、このコードのassert_eq!panicします。入れた順に来るかと思ったし、キーの値でソートしたものを取り出したりできるんじゃないかと思ったんだが、見つけられなかった。また、構造体のソートについて調べると自力でやる方法が見つかったりしたが、結構大変だった。

fn main() {
    use std::{collections::HashMap, io::Write};

    #[derive(Debug, PartialEq, Clone)]
    struct Example {
        name: String,
        age: u8,
    };

    let example1 = Example {
        name: "あんこ".into(),
        age: 16,
    };

    let example2 = Example {
        name: "あんこ".into(),
        age: 105,
    };

    let example3 = Example {
        name: "えなこ".into(),
        age: 24,
    };

    let mut a: HashMap<usize, Example> = HashMap::new();
    a.insert(1, example1.clone());
    a.insert(2, example2.clone());
    a.insert(3, example3.clone());

    let res = a.into_iter().map(|(_, val)| val).collect::<Vec<Example>>();

    assert_eq!(vec![example1, example2, example3], res);
}

で、しばらくしてもう一度調べていたら Eq PartialEq Ord PartialOrd をDriveで追加することで普通にソートができるようです。

fn main() {
    use std::{collections::HashMap, io::Write};

    #[derive(Debug, Eq, Ord, PartialEq, PartialOrd, Clone)]
    struct Example {
        name: String,
        age: u8,
    };

    let example1 = Example {
        name: "あんこ".into(),
        age: 16,
    };

    let example2 = Example {
        name: "あんこ".into(),
        age: 105,
    };

    let example3 = Example {
        name: "えなこ".into(),
        age: 24,
    };

    let mut a: HashMap<usize, Example> = HashMap::new();
    a.insert(1, example1.clone());
    a.insert(2, example2.clone());
    a.insert(3, example3.clone());

    let mut res = a.into_iter().map(|(_, val)| val).collect::<Vec<Example>>();
    res.sort();

    assert_eq!(vec![example1, example2, example3], res);
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA