Day 2:雜湊映射 HashMap

學習目標

  • 建立、讀取、更新 HashMap
  • 用 entry API 安全更新
  • 理解「#1 依賴前一個值」的計數模式

今日重點

建立與讀取

use std::collections::HashMap;

let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);

// 讀取
let team = String::from("Blue");
let score = scores.get(&team);   // Option<&i32>
println!("{:?}", score);

// 迭代
for (key, value) in &scores {
    println!("{}: {}", key, value);
}

更新:entry API

// or_insert:沒有才插入
scores.entry(String::from("Green")).or_insert(25);

// 更新既有的
let count = scores.entry(String::from("Blue")).or_insert(0);
*count += 1;   // 用 * 解引用修改

計數模式(依賴前一個值)

let text = "hello world wonderful world";
let mut word_count = HashMap::new();

for word in text.split_whitespace() {
    let count = word_count.entry(word).or_insert(0);
    *count += 1;
}
println!("{:?}", word_count);   // {"hello":1, "world":2, ...}

練習

use std::collections::HashMap;

fn main() {
    let mut inventory = HashMap::new();
    inventory.insert(String::from("apple"), 3);
    inventory.insert(String::from("banana"), 5);

    // 1. 把 apple 值改為 +2
    *inventory.entry(String::from("apple")).or_insert(0) += 2;

    // 2. 加 10 顆 new fruit
    inventory.insert(String::from("grape"), 10);

    // 3. 印出所有 items 及數量
    for (k, v) in &inventory { println!("{}: {}", k, v); }
}

自我檢查

  • 會建立與讀取 HashMap
  • 理解 insert / get / entry API
  • 能寫出「計數每個字出現次數」的程式
  • 知道 *count += 1 為什麼要解引用

深入連結

  • The Book 第 8 章「Hash Maps」