🎓 A1Learner
🔍

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?