隱私權政策

搜尋此網誌

技術提供:Blogger.

關於我自己

我的相片
目前從事軟體相關行業,喜歡閱讀、健身、喝調酒。習慣把遇到的問題記下來,每天做一些整理方便自己以後查。 Python、Rust、Kotlin等程式語言皆為自學,目前比較著重在Rust語言,歡迎一起討論。

2023年12月21日 星期四

Rust HashMap概述4 - 迭代運用、數組轉換、根據value排序


HashMap4

前面打了三篇心得

Rust HashMap概述1 - key與value集合 ~ LaGee-Blog (lageeblog.blogspot.com)

Rust HashMap概述2 - get、get_key_value、雙重HashMap ~ LaGee-Blog (lageeblog.blogspot.com)

Rust HashMap概述3 - 刪除資料clear、drain、remove、retain ~ LaGee-Blog (lageeblog.blogspot.com)

這篇第四篇

主要講述RustMap如何跟迭代運用

會使用到map和for迴圈

以及數組和HashMap互相轉換

最後會示範一下如何用把HashMap裡面的東西照著value排序


迭代

iter[1]

pub fn iter(&self) -> Iter<'_, K, V>

iter_mut[2]

pub fn iter_mut(&mut self) -> IterMut<'_, K, V> ⓘ


HashMap也是可以迭代

有兩種方式

一種是iter、一種是iter_mut

回傳key和value

iter_mut可以直接對迭代器中數值更改


假設我是一個佛心老師

想要把成績都開根號乘以10

可以這樣子

use std::collections::HashMap;

fn main() {
    let score_map: HashMap<&str, u8> = HashMap::from([
        ("Chinese", 64),
        ("Math", 81),
        ("English", 36),
    ]);
    let map_iter: HashMap<&str, u8> = score_map
        .iter()
        .map(|(k, v)| (*k, ((*v as f64).sqrt() * 10.0) as u8))
        .collect();
    println!("before bonus score: {:?}", score_map);
    println!("after bonus score: {:?}", map_iter);
}
before bonus score: {"Chinese": 64, "Math": 81, "English": 36} after bonus score: {"Chinese": 80, "Math": 90, "English": 60}

先透過iter將score_map放入迭代器中

使用map[3],閉包內需要輸入兩個值

因為最後collect是回傳key和value,因此map裡面也需要回傳兩個值

這題不對key做處理,只對value做處理

因此value轉f64,開根號sqrt後再乘以10,並且轉成u8以符合型態

最後輸出可以看到所有數值都開根號乘10了


而都使用iter了當然也可以使用for迴圈

    let score_map: HashMap<&str, u8> = HashMap::from([
        ("Chinese", 64),
        ("Math", 81),
        ("English", 36),
    ]);
    for (k,v) in score_map {
        println!("{}, after bonus score: {}", k, (v as f64).sqrt() * 10.0);
    }
Chinese, after bonus score: 80 Math, after bonus score: 90 English, after bonus score: 60

for的前面要放兩組變數

分別代表key和value

如果想要直接修改HashMap的值可以使用iter_mut

    let mut score_map: HashMap<&str, u8> = HashMap::from([
        ("Chinese", 64),
        ("Math", 81),
        ("English", 36),
    ]);
    for (_,v) in score_map.iter_mut() {
        *v = ((*v as f64).sqrt() * 10.0) as u8;
    }
    println!("after bouns score: {:?}", score_map);
after bouns score: {"Math": 90, "English": 60, "Chinese": 80}

要對其解引用

之後可以直接更改HashMap裡面的值


數組、HashMap轉換

數組和HashMap是可以互相轉換的

數組轉HashMap

use std::collections::HashMap;

fn main() {
    let score_vec = vec![("Chinese", 64), ("Math", 81), ("English", 36)];
    let score_map = score_vec.into_iter().collect::<HashMap<_,_>>();
    // println!("{:?}", score_vec);  panic
    println!("{:?}", score_map);
}
{"English": 36, "Math": 81, "Chinese": 64}

數組內需要有一個由元組組成的數組

元組內兩個值,代表K和V

要注意數組轉HashMap是要所有權的

如果是用引用iter(),會發生panic

因此要使用iter_mut把所有權轉給迭代器,之後collect

輸出結果會把前面那個科目當作K,後面數字當作V


HashMap轉數組

use std::collections::HashMap;

fn main() {
    let score_map: HashMap<&str, u8> =
        HashMap::from([("Chinese", 64), ("Math", 81), ("English", 36)]);
    let score_vec: Vec<(&str, u8)> = score_map.into_iter().collect::<Vec<_>>();
    // println!("map: {:?}", score_map); panic
    println!("vec: {:?}", score_vec);
}
vec: [("Chinese", 64), ("Math", 81), ("English", 36)]

HashMap轉數組一樣

使用into_iter轉移所有權

如果沒轉移所有權只會拿到引用值

轉移後數組裡面一樣是元組


根據value排序

HashMap是一個無序的集合

意思是我不能保證每次輸出的順序都一樣

假設我希望把順序依照value排序

需要轉vec後使用sort_by或sort_by_key排序

use std::collections::HashMap;

fn main() {
    let score_map: HashMap<&str, u8> =
        HashMap::from([("Chinese", 64), ("Math", 81), ("English", 36)]);
    println!("before sort: {:?}", score_map);
    let mut score_vec = score_map.iter().collect::<Vec<_>>();
    score_vec.sort_by_key(|(_, &v)| v);
    println!("after sort: {:?}", score_vec);
}
before sort: {"Math": 81, "English": 36, "Chinese": 64} after sort: [("English", 36), ("Chinese", 64), ("Math", 81)]

這邊使用sort_by_key[4]排序

轉成vec後

使用sort_by_key根據value

輸出後可看到有排序

如果需要轉回HashMap可以用上面的方法轉


參考資料

[1] https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.iter

[2] https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.iter_mut

[3] https://lageeblog.blogspot.com/2023/10/rust-map.html

[4] https://doc.rust-lang.org/std/primitive.slice.html#method.sort_by_key


0 comments:

張貼留言