What it is
Itertools extends Rust's iterators with dozens of adaptors the standard library omits: chunking, grouping, cartesian products, deduplication and more.
Import the Itertools trait to add methods to every existing iterator. Everything stays lazy and composes with the standard adaptors.
Installation
cargo add itertoolsGetting started
The smallest useful thing you can do with it, and what each part means.
rust
use itertools::Itertools;
// Join without a manual fold.
let list = names.iter().join(", ");
// Group consecutive equal keys (sort first for global grouping).
for (year, books) in books.iter().chunk_by(|b| b.year).into_iter() {
println!("{year}: {}", books.count());
}
// Deduplicate while preserving order.
let unique: Vec<_> = ids.into_iter().unique().collect();
// Sliding windows and fixed chunks.
for pair in prices.iter().tuple_windows::<(_, _)>() {
println!("change: {}", pair.1 - pair.0);
}
// Split successes from failures in one pass.
let (ok, failed): (Vec<_>, Vec<_>) = results.into_iter().partition_result();Advanced usage
Where the library earns its place over a simpler alternative.
rust
// Every pair, without repeats.
for (a, b) in items.iter().tuple_combinations() {
compare(a, b);
}
// Cartesian product across two sets.
let grid: Vec<_> = rows.iter().cartesian_product(cols.iter()).collect();
// Stop at the first error and return it.
let parsed: Result<Vec<i32>, _> = inputs.iter()
.map(|s| s.parse::<i32>())
.try_collect();
// Exactly one match, or an error either way.
let only = matches.into_iter().exactly_one()?;Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- chunk_by produces more groups than expected
- It groups consecutive items only. Sort by the same key first.
- cannot borrow while iterating
- Several adaptors return borrowed lazy iterators. Collect into a Vec before mutating the source.
Best practices
- Sort before chunk_by unless you genuinely want runs of adjacent items.
- Prefer these adaptors over hand-written loops — they are lazy and allocate less.
- Check std first; several former Itertools methods are now stable there.
- Use exactly_one when a query should return precisely one result; it makes the invariant explicit.
Background
Why it exists, and what it was reacting to.
The standard Iterator trait is deliberately minimal. Itertools collects the combinators that repeatedly prove useful without meriting inclusion in std.
