Counting the entries of a HashMap
A HashMap holds key-value pairs, and a common question about it is how many pairs it holds right now. The answer comes from the len() method:
use std::collections::HashMap;
fn main() {
let mut scores: HashMap<&str, i32> = HashMap::new();
scores.insert("Alice", 95);
scores.insert("Bob", 87);
scores.insert("Charlie", 72);
let n = scores.len();
println!("{}", n);
}
This prints 3. Each key counts once, whatever its value is. The length is the number of keys, not the sum or the size of the values.
The type of len()
The method returns a usize, the unsigned integer type Rust uses for sizes and indexes. So let n = scores.len(); gives n the type usize, and the compiler works that out on its own. You rarely need to write it down.
It matters when you mix the length with other numbers. A usize can't be negative, and Rust won't silently combine it with an i32. To compare the length to a signed number, convert one side with as. For a map with 2 entries, count as i32 - 5 is -3. Doing the subtraction on the usize directly would not give -3: in the optimized build the lessons use it wraps around to a huge number, and in a debug build it panics.
Checking for an empty map
To ask whether a map has no entries, use is_empty() instead of comparing len() with 0. It returns a bool and says what you mean:
let empty: HashMap<&str, i32> = HashMap::new();
println!("{}", scores.is_empty());
println!("{}", empty.is_empty());
println!("{}", empty.len());
With the scores map above, the output is:
false
true
0
How the length changes
The length follows the entries, so it moves as you change the map:
- Inserting a new key raises it by one.
- Inserting a key that already exists replaces the value and leaves the length unchanged, because keys are unique.
remove(key)lowers it by one when the key was present.
For example, start with an empty map and insert "a" with 1, insert "a" again with 2, then insert "b" with 3. The length is 2, not 3, since the second insert replaced the first. After remove("a") the length is 1.
That is why the length is the right tool for counting distinct things. If you insert every word of a text as a key, len() afterwards is the number of different words.
Length versus the number of items you added
The same method name exists on other collections, and it counts what each collection holds. A Vec counts its elements, including repeats. A HashMap counts distinct keys. The difference shows when you count words:
let words = vec!["to", "be", "or", "not", "to", "be"];
let mut seen: HashMap<&str, i32> = HashMap::new();
for w in &words {
*seen.entry(w).or_insert(0) += 1;
}
println!("{} {}", words.len(), seen.len());
This prints 6 4: six words in the vector, four different ones in the map. Be careful with strings, too: len() on a String or &str counts bytes, not characters, so "h\u{e9}llo".len() is 6.
The exercise
The editor gives you a map with three entries:
let scores = HashMap::from([("Alice", 95), ("Bob", 87), ("Charlie", 72)]);
The task has one step: below the map, declare a variable named count with let and give it the number of entries in scores. Call len() on the map and store the result. The map is not modified here, so a plain let without mut is enough, and len() only reads the map. The reference solution is:
let scores = HashMap::from([("Alice", 95), ("Bob", 87), ("Charlie", 72)]);
let count = scores.len();
Here count holds 3.
Common mistakes
- Writing
scores.lenwithout the parentheses.lenis a method, so it needs the call. - Expecting the length to include removed entries. Once a key is removed, it no longer counts.
- Forgetting the import.
HashMaplives instd::collections, so a program needsuse std::collections::HashMap;before it can name the type. - Subtracting from the length of an empty map.
len() - 1on an empty map is ausizesubtraction below zero, so convert first or checkis_empty().
Key takeaways
len()returns the number of key-value pairs as ausize.is_empty()is the clear way to ask whether the map has no entries.- Duplicate keys never add to the length, because inserting an existing key only replaces its value.
