13.2 Common Iterator Methods
This section introduces widely used iterator methods. We categorize them into adapters (lazy) and consumers (eager).
13.2.1 Iterator Adapters (Lazy)
map()
Applies a closure or function to each element, returning a new iterator of transformed items:
fn main() { let numbers = vec![1, 2, 3, 4]; let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect(); println!("{:?}", doubled); // [2, 4, 6, 8] }
You can pass a named function if it matches the required signature:
fn double(i: &i32) -> i32 { i * 2 } fn main() { let numbers = vec![1, 2, 3, 4]; let doubled: Vec<i32> = numbers.iter().map(double).collect(); println!("{:?}", doubled); // [2, 4, 6, 8] }
filter()
Retains only elements that satisfy a given predicate:
fn main() { let numbers = vec![1, 2, 3, 4, 5, 6]; let even: Vec<i32> = numbers.iter().filter(|&&x| x % 2 == 0).cloned().collect(); println!("{:?}", even); // [2, 4, 6] }
take()
Yields the first n elements:
fn main() { let numbers = vec![1, 2, 3, 4, 5]; let first_three: Vec<i32> = numbers.iter().take(3).cloned().collect(); println!("{:?}", first_three); // [1, 2, 3] }
skip()
Skips the first n elements, yielding the remainder:
fn main() { let numbers = vec![1, 2, 3, 4, 5]; let skipped: Vec<i32> = numbers.iter().skip(2).cloned().collect(); println!("{:?}", skipped); // [3, 4, 5] }
take_while()
and skip_while()
take_while()
yields items until the predicate becomes false.skip_while()
skips items while the predicate is true, yielding the rest once the predicate is false.
fn main() { let numbers = vec![1, 2, 3, 1, 2]; let initial_run: Vec<i32> = numbers .iter() .cloned() .take_while(|&x| x < 3) .collect(); println!("{:?}", initial_run); // [1, 2] let after_first_three: Vec<i32> = numbers .iter() .cloned() .skip_while(|&x| x < 3) .collect(); println!("{:?}", after_first_three); // [3, 1, 2] }
enumerate()
Yields an (index, element)
pair:
fn main() { let names = vec!["Alice", "Bob", "Charlie"]; for (index, name) in names.iter().enumerate() { print!("{}: {}; ", index, name); } // 0: Alice; 1: Bob; 2: Charlie; }
13.2.2 Consuming Iterator Methods (Eager)
collect()
Consumes the iterator, gathering all elements into a collection (e.g., Vec<T>
, String
, etc.):
fn main() { let numbers = vec![1, 2, 3]; let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect(); println!("{:?}", doubled); // [2, 4, 6] }
sum()
Computes the sum of the elements:
fn main() { let numbers = vec![1, 2, 3, 4, 5]; let total: i32 = numbers.iter().sum(); println!("Total: {}", total); // Total: 15 }
fold()
Combines elements into a single value using a custom operation:
fn main() { let numbers = vec![1, 2, 3, 4]; let product = numbers.iter().fold(1, |acc, &x| acc * x); println!("{}", product); // 24 }
for_each()
Applies a closure to each item:
fn main() { let numbers = vec![1, 2, 3]; numbers.iter().for_each(|x| print!("{}, ", x)); // 1, 2, 3, }
any()
and all()
any()
: Returnstrue
if at least one element satisfies the predicate.all()
: Returnstrue
if every element satisfies the predicate.
fn main() { let numbers = vec![2, 4, 6, 7]; let has_odd = numbers.iter().any(|&x| x % 2 != 0); let all_even = numbers.iter().all(|&x| x % 2 == 0); println!("Has odd? {}", has_odd); // true println!("All even? {}", all_even); // false }
These methods short-circuit as soon as the outcome is known.