Rust
collect
Turn an iterator into a collection with collect.
collect
collect turns an iterator into any collection implementing FromIterator. The target type comes from the variable type or the turbofish:
let v: Vec<char> = "abc".chars().collect();
let s: String = vec!['x', 'y'].into_iter().collect();
let k: std::collections::HashSet<i32> = [1, 1, 2].into_iter().collect();
The same chain can produce different collections just by changing the target type.
Collecting with errors
To convert all texts to numbers and give up if even one is invalid:
let iyi: Result<Vec<i32>, _> = ["4", "5"].iter().map(|s| s.parse::<i32>()).collect();
let kotu: Result<Vec<i32>, _> = ["1", "x"].iter().map(|s| s.parse::<i32>()).collect();
println!("{:?} {}", iyi, kotu.is_err()); // Ok([4, 5]) true
unzip splits an iterator of pairs into two collections: let (a, b): (Vec<_>, Vec<_>) = [(1, 'a'), (2, 'b')].into_iter().unzip();
Exercise Collect with validation
Collect the arrays ["1", "2", "x"] and ["4", "5"] into Result<Vec<i32>, _> with parse::<i32>(). Print the result of is_err() for the first and the second with {:?}, separated by a space.
Show example solution
fn main() {
let r1: Result<Vec<i32>, _> = ["1", "2", "x"].iter().map(|s| s.parse::<i32>()).collect();
let r2: Result<Vec<i32>, _> = ["4", "5"].iter().map(|s| s.parse::<i32>()).collect();
println!("{} {:?}", r1.is_err(), r2);
}
Test yourself
-
What happens when an iterator of <code>Result</code> items is collected into <code>Result<Vec<T>, E></code>?
- If all are Ok, Ok(vector); at the first Err it stops and returns that error
- Errs are skipped
- It panics
- It doesn't compile
Show answer
If all are Ok, Ok(vector); at the first Err it stops and returns that error — This is the shortest way to validate all inputs and return with a single error. The same holds for Option.
-
Collect into a String
let s: ____ = vec!['x', 'y'].into_iter().collect();
Show answer
let s: String = vec!['x', 'y'].into_iter().collect();
-
Target type and result
- Vec<char> ← "ab".chars()
- ['a', 'b']
- String ← ['x', 'y']
- "xy"
- HashSet ← [1, 1, 2]
- 2 elements
- Result<Vec<i32>, _> ← ["1", "x"]
- Err
Next lesson: Lazy evaluation