WeCodeAcademy

Step 4: The Rust version

Rust looks like C++ here but adds guarantees. A HashMap counts words with the entry API (*counts.entry(word).or_insert(0) += 1), split with a closure breaks the text, and sort_by with .then() sorts by count then name. The function returns a Vec<(String, usize)> which the caller owns.

ExampleRust
use std::collections::HashMap;

fn count_words(text: &str) -> Vec<(String, usize)> {
    let mut counts: HashMap<String, usize> = HashMap::new();
    for word in text
        .to_lowercase()
        .split(|c: char| !c.is_alphabetic())
        .filter(|w| !w.is_empty())
    {
        *counts.entry(word.to_string()).or_insert(0) += 1;
    }
    let mut sorted: Vec<(String, usize)> = counts.into_iter().collect();
    sorted.sort_by(|a, b| b.1.cmp(&a.1).then(a.0.cmp(&b.0)));
    sorted
}

fn main() {
    let text = "The quick brown fox jumps over the lazy dog. The end!";
    for (word, count) in count_words(text) {
        println!("{:<6} {}", word, count);
    }
}
Output
the    3
brown  1
dog    1
end    1
fox    1
jumps  1
lazy   1
over   1
quick  1

The compiler proved that no reference outlives its data and that nothing is used after being moved, so there are no hidden memory bugs, and there is no garbage collector either. The price is learning the ownership rules; the reward is safety with C-like speed.

Quick check

What does the entry API do in the Rust version?

Finish the quick check (and any code exercise) to complete this lesson, or mark it done yourself.

Tip: use the left and right arrow keys to move between lessons.