Activity 29: From Loops to Iterators
Goal: Rewrite loop-based code using iterators and closures.
Setup: Open Rust Playground, keep the main(){...} part on the outside, and start with this data:
#![allow(unused)] fn main() { let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; }
For each problem, think about:
- Do you need
*numor&numor justnumin your closures? - When do you need
.copied()or.cloned()? - What's the type of the iterator at each step?
To wrap up, submit the problem number and solution to the last problem you were able to complete by the end of class.
Problem 1:
Given this loop:
#![allow(unused)] fn main() { let mut result = Vec::new(); for num in &numbers { result.push(num + 5); } println!("result: {:?}", result); }
Rewrite using .map() and .collect()
Problem 2:
Given this loop:
#![allow(unused)] fn main() { let mut result = Vec::new(); for num in &numbers { if num % 3 == 0 { result.push(*num); } } println!("result: {:?}", result); }
Rewrite using .filter() and .collect()
Problem 3:
Given this loop:
#![allow(unused)] fn main() { let mut result = Vec::new(); for num in &numbers { if *num > 5 { result.push(num * 2); } } println!("result: {:?}", result); }
Rewrite using .filter(), .map(), and .collect()
Problem 4:
Given this loop:
#![allow(unused)] fn main() { let mut result = Vec::new(); for num in &numbers { let squared = num * num; if squared > 20 { result.push(squared); } } println!("result: {:?}", result); }
Rewrite using .map(), .filter(), and .collect()
Problem 5:
Given this loop:
#![allow(unused)] fn main() { let mut result = Vec::new(); for num in &numbers { if num % 2 == 0 { // Keep evens let tripled = num * 3; if tripled > 10 { // Keep if > 10 result.push(tripled); } } } println!("result: {:?}", result); }
Rewrite using .map(), .filter(), and .collect()
Problem 6:
Given this loop:
#![allow(unused)] fn main() { let mut count = 0; for num in &numbers { if num % 2 == 0 && *num > 4 { count += 1; } } println!("count: {}", count); }
Rewrite using .filter() and .count()
Problem 7:
Given this loop:
#![allow(unused)] fn main() { let mut sum = 0; for num in &numbers { if *num < 8 { sum += num * 2; } } println!("sum: {}", sum); }
Rewrite using .filter(), .map(), and .sum()
Challenge Problem:
Given this loop:
#![allow(unused)] fn main() { let mut result = Vec::new(); let mut running_sum = 0; for num in &numbers { running_sum += num; result.push(running_sum); } println!("result: {:?}", result); }
Rewrite using .fold() with a multi-line closure. Think about:
- What should the initial accumulator value be? (Hint: you need to track both the running sum AND the result vector, can use a tuple to hold both)
- The closure needs to update both parts of the tuple and return it
- Use
{ }syntax for a multi-line closure