Lesson 17 / 25

Vec, HashMap and String

The everyday collections.

Growable, keyed, UTF-8

Vec<T> is a growable array; sort with sort_by and closures. HashMap<K, V> maps keys to values; the entry API (entry(k).or_insert(0)) inserts or updates without double lookups. String is an owned, growable, UTF-8 string: len() counts bytes, not characters, so text in scripts like Devanagari has more bytes than characters. HashMap iteration order is unspecified, so sort when order matters.

Expressive data processing

Vec, HashMap and String cover most needs; iterator chains process them clearly and efficiently.

Three ideas: collections, iterators and closures, strings and slices.
Figure 6.1 — Collections, iterators and slices.

Sorting a Vec, counting words, UTF-8 strings, run

I ran this with Rust 1.99.0 (cargo run, edition 2024, standard library only). The cart is sorted by quantity; the entry API counts words (sorted by count then word for stable output); the string with Hindi text is 25 bytes but 13 characters.

use std::collections::HashMap;

fn main() {
    let mut cart: Vec<(&str, u32)> = vec![("pen", 2), ("ink", 1)];
    cart.push(("notebook", 3));
    cart.sort_by(|a, b| b.1.cmp(&a.1));
    println!("{cart:?}");

    let text = "the cat saw the dog and the cat ran";
    let mut counts: HashMap<&str, usize> = HashMap::new();
    for word in text.split_whitespace() {
        *counts.entry(word).or_insert(0) += 1;    // entry API: insert or update
    }
    let mut top: Vec<_> = counts.into_iter().collect();
    top.sort_by(|a, b| b.1.cmp(&a.1).then(a.0.cmp(b.0)));
    println!("{:?}", &top[..3]);

    let mut s = String::from("Hello");
    s.push_str(", नमस्ते");
    println!("{s} | bytes={} chars={}", s.len(), s.chars().count());
}

Output:

[("notebook", 3), ("pen", 2), ("ink", 1)]
[("the", 3), ("cat", 2), ("and", 1)]
Hello, नमस्ते | bytes=25 chars=13

Use the entry API

entry().or_insert() and and_modify() make insert-or-update code shorter and faster.

Quick check: What does String::len() return for non-ASCII text?

  • The number of words
  • The number of characters
  • The number of bytes, which can exceed the number of characters
  • Always zero
Answer

The number of bytes, which can exceed the number of characters — Strings are UTF-8 bytes.