13.2 Common Iterator Methods
The Iterator
trait provides a rich set of default methods built upon the fundamental next()
method.
13.2.1 Adapters (Lazy Methods Returning Iterators)
map(closure)
: Appliesclosure
to each element, creating an iterator of the results. Signature:|Self::Item| -> OutputType
.#![allow(unused)] fn main() { let squares: Vec<_> = vec![1, 2, 3].iter().map(|&x| x * x).collect(); // [1, 4, 9] }
filter(predicate)
: Creates an iterator yielding only elements for which thepredicate
closure returnstrue
. Signature:|&Self::Item| -> bool
.#![allow(unused)] fn main() { let evens: Vec<_> = vec![1, 2, 3, 4].iter().filter(|&&x| x % 2 == 0).copied() .collect(); // [2, 4] }
filter_map(closure)
: Filters and maps simultaneously. Theclosure
returns anOption<OutputType>
. OnlySome(value)
results are yielded (unwrapped). Signature:|Self::Item| -> Option<Output>
. Ideal for parsing or fallible transformations.#![allow(unused)] fn main() { let nums_str = ["1", "two", "3", "four"]; let nums: Vec<i32> = nums_str.iter().filter_map(|s| s.parse().ok()).collect(); // [1, 3] }
enumerate()
: Wraps the iterator to yield(index, element)
pairs, starting at index 0.fn main() { let items = vec!["a", "b"]; for (i, item) in items.iter().enumerate() { println!("{}: {}", i, *item); // Output: 0: a, 1: b } }
peekable()
: Creates an iterator allowing inspection of the next element via.peek()
without consuming it from the underlying iterator. Useful for lookahead.take(n)
: Yields at most the firstn
elements.skip(n)
: Skips the firstn
elements, then yields the rest.take_while(predicate)
: Yields elements whilepredicate
returnstrue
. Stops permanently oncepredicate
returnsfalse
.skip_while(predicate)
: Skips elements whilepredicate
returnstrue
. Yields all subsequent elements (including the one that first returnedfalse
).step_by(step)
: Creates an iterator yielding everystep
-th element (e.g., 0th, step-th, 2*step-th, …).zip(other_iterator)
: Combines two iterators into a single iterator of pairs(a, b)
. Stops when the shorter iterator is exhausted.#![allow(unused)] fn main() { let nums = [1, 2]; let letters = ['a', 'b', 'c']; let pairs: Vec<_> = nums.iter().zip(letters.iter()).collect(); // [(&1, &'a'), (&2, &'b')] }
chain(other_iterator)
: Yields all elements from the first iterator, then all elements from the second. Both iterators must yield the sameItem
type.#![allow(unused)] fn main() { let v1 = [1, 2]; let v2 = [3, 4]; let combined: Vec<_> = v1.iter().chain(v2.iter()).copied().collect(); // [1, 2, 3, 4] }
cloned()
: Converts an iterator yielding&T
into one yieldingT
by callingclone()
on each element. RequiresT: Clone
.copied()
: Converts an iterator yielding&T
into one yieldingT
by bitwise copying the value. RequiresT: Copy
. Generally preferred overcloned()
forCopy
types for efficiency.rev()
: Reverses the direction of an iterator. Requires the iterator to implementDoubleEndedIterator
.
13.2.2 Consumers (Eager Methods Consuming the Iterator)
collect()
/collect::<CollectionType>()
: Consumes the iterator, gathering elements into a specified collection (e.g.,Vec<T>
,HashMap<K, V>
,String
,Result<Vec<T>, E>
). Type inference often works, but sometimes explicit type annotation (::<Type>
) is needed.#![allow(unused)] fn main() { let doubled: Vec<i32> = vec![1, 2].iter().map(|&x| x * 2).collect(); let chars: String = ['h', 'i'].iter().collect(); }
for_each(closure)
: Consumes the iterator, callingclosure
for each element. Used for side effects (like printing). Signature:|Self::Item|
.#![allow(unused)] fn main() { vec![1, 2].iter().for_each(|x| println!("{}", x)); }
sum()
/product()
: Consumes the iterator, computing the sum or product. RequiresItem
to implementstd::iter::Sum<Self::Item>
orstd::iter::Product<Self::Item>
, respectively.#![allow(unused)] fn main() { let total: i32 = vec![1, 2, 3].iter().sum(); // 6 let factorial: i64 = (1..=5).product(); // 120 }
fold(initial_value, closure)
: Consumes the iterator, applying an accumulator function.closure
takes(accumulator, element)
and returns the new accumulator value. Powerful for custom aggregations. Signature:(Accumulator, Self::Item) -> Accumulator
.#![allow(unused)] fn main() { let product = vec![1, 2, 3].iter().fold(1, |acc, &x| acc * x); // 6 }
reduce(closure)
: Similar tofold
, but uses the first element as the initial accumulator. ReturnsOption<Self::Item>
(None if the iterator is empty). Signature:(Self::Item, Self::Item) -> Self::Item
.count()
: Consumes the iterator and returns the total number of items yielded (usize
).last()
: Consumes the iterator and returns the last element as anOption<Self::Item>
.nth(n)
: Consumes the iterator up to and including the n-th element (0-indexed) and returns it asOption<Self::Item>
. Consumes all prior elements. Efficient forExactSizeIterator
.any(predicate)
: Consumes the iterator, returningtrue
if any element satisfiespredicate
. Short-circuits (stops early iftrue
is found). Signature:|Self::Item| -> bool
.all(predicate)
: Consumes the iterator, returningtrue
if all elements satisfypredicate
. Short-circuits (stops early iffalse
is found). Signature:|Self::Item| -> bool
.find(predicate)
: Consumes the iterator, returning the first element satisfyingpredicate
as anOption<Self::Item>
. Short-circuits. Signature:|&Self::Item| -> bool
.#![allow(unused)] fn main() { let nums = [1, 2, 3, 4]; let first_even: Option<&i32> = nums.iter().find(|&&x| x % 2 == 0); // Some(&2) }
find_map(closure)
: Consumes the iterator, applyingclosure
to each element. Returns the first non-None
result produced by the closure. Signature:|Self::Item| -> Option<ResultType>
. Short-circuits.position(predicate)
: Consumes the iterator, returning the index (usize
) of the first element satisfyingpredicate
asOption<usize>
. Short-circuits. Signature:|Self::Item| -> bool
.