Rust Iterators Basics
An iterator is a value that hands out items one at a time, on request. A for loop already pulls items this way from the group it walks.
iter() lends each item
iter() walks a group by lending each item. The group stays whole, as the last line proves:
fn main() {
let scores = [10, 20, 30];
for s in scores.iter() {
println!("score = {}", s);
}
println!("still {} scores", scores.len());
}A chain: map, filter, collect
map changes each item, filter keeps the ones that pass, and collect gathers the survivors into a new Vec:
fn main() {
let scores = [3, 8, 12, 5];
let doubled: Vec<i32> = scores
.iter()
.map(|n| n * 2)
.filter(|n| *n > 10)
.collect();
println!("{:?}", doubled);
}A chain does nothing until pulled
Building a chain runs none of it. The doubling lines print only after collect starts pulling:
fn main() {
let scores = [1, 2, 3];
let chain = scores.iter().map(|n| {
println!("doubling {}", n);
n * 2
});
println!("chain built, nothing ran yet");
let doubled: Vec<i32> = chain.collect();
println!("{:?}", doubled);
}sum pulls too
collect is one way to pull a chain. sum pulls as well, and adds the items as they arrive:
fn main() {
let words = ["rust", "is", "fun"];
let total_letters: usize = words.iter().map(|w| w.len()).sum();
println!("letters = {}", total_letters);
}Example
fn main() {
let prices = [250, 80, 120, 40];
let deals: Vec<i32> = prices
.iter()
.filter(|p| **p < 200)
.map(|p| p - 10)
.collect();
println!("deals = {:?}", deals);
let total: i32 = deals.iter().sum();
println!("total = {}", total);
}Key points
- Nothing moves until a pull asks for the next item.
- iter() borrows each item in turn.
- The collection itself stays whole and usable afterwards.
- map and filter only describe a chain. They run nothing by themselves.
- A chain starts working when something pulls, like collect, sum, or a for loop.
In this example, the chain starts from prices. filter keeps the prices under 200, so 250 drops out. map takes 10 off each survivor. collect gathers the three results into deals. A second, shorter chain then sums deals into 210. Rust Iterators, in the Intermediate course, goes deeper from here — many more chain steps, and iterators you write yourself.
Note
A chain passes each item through every step at once, so no half-built lists pile up in between.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
When does the work inside a map and filter chain actually happen?