From 1287d9d70800c671161e17f2c22bbc2d477caff8 Mon Sep 17 00:00:00 2001 From: My Chiffon Nguyen Date: Sat, 22 Jun 2024 17:38:03 +0200 Subject: [PATCH] 18 Iterators & collections --- exercises/18_iterators/iterators1.rs | 10 +++---- exercises/18_iterators/iterators2.rs | 12 ++++++--- exercises/18_iterators/iterators3.rs | 40 ++++++++++++++++++---------- exercises/18_iterators/iterators4.rs | 7 ++--- exercises/18_iterators/iterators5.rs | 14 +++++++--- 5 files changed, 53 insertions(+), 30 deletions(-) diff --git a/exercises/18_iterators/iterators1.rs b/exercises/18_iterators/iterators1.rs index 31076bb9..fd9c6f53 100644 --- a/exercises/18_iterators/iterators1.rs +++ b/exercises/18_iterators/iterators1.rs @@ -9,18 +9,18 @@ // Execute `rustlings hint iterators1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE +// Listing 13-12: https://doc.rust-lang.org/book/ch13-02-iterators.html#the-iterator-trait-and-the-next-method #[test] fn main() { let my_fav_fruits = vec!["banana", "custard apple", "avocado", "peach", "raspberry"]; - let mut my_iterable_fav_fruits = ???; // TODO: Step 1 + let mut my_iterable_fav_fruits = my_fav_fruits.iter(); assert_eq!(my_iterable_fav_fruits.next(), Some(&"banana")); - assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 2 + assert_eq!(my_iterable_fav_fruits.next(), Some(&"custard apple")); assert_eq!(my_iterable_fav_fruits.next(), Some(&"avocado")); - assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 3 + assert_eq!(my_iterable_fav_fruits.next(), Some(&"peach")); assert_eq!(my_iterable_fav_fruits.next(), Some(&"raspberry")); - assert_eq!(my_iterable_fav_fruits.next(), ???); // TODO: Step 4 + assert_eq!(my_iterable_fav_fruits.next(), None); } diff --git a/exercises/18_iterators/iterators2.rs b/exercises/18_iterators/iterators2.rs index dda82a08..f239b639 100644 --- a/exercises/18_iterators/iterators2.rs +++ b/exercises/18_iterators/iterators2.rs @@ -6,7 +6,7 @@ // Execute `rustlings hint iterators2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE +// https://doc.rust-lang.org/book/ch13-02-iterators.html#methods-that-produce-other-iterators // Step 1. // Complete the `capitalize_first` function. @@ -15,7 +15,7 @@ pub fn capitalize_first(input: &str) -> String { let mut c = input.chars(); match c.next() { None => String::new(), - Some(first) => ???, + Some(first) => first.to_uppercase().to_string() + c.as_str(), } } @@ -24,7 +24,7 @@ pub fn capitalize_first(input: &str) -> String { // Return a vector of strings. // ["hello", "world"] -> ["Hello", "World"] pub fn capitalize_words_vector(words: &[&str]) -> Vec { - vec![] + words.iter().map(|word| capitalize_first(word)).collect() } // Step 3. @@ -32,7 +32,11 @@ pub fn capitalize_words_vector(words: &[&str]) -> Vec { // Return a single string. // ["hello", " ", "world"] -> "Hello World" pub fn capitalize_words_string(words: &[&str]) -> String { - String::new() + words + .iter() + .map(|word| capitalize_first(word)) + .collect::>() + .join("") } #[cfg(test)] diff --git a/exercises/18_iterators/iterators3.rs b/exercises/18_iterators/iterators3.rs index 29fa23a3..df4126ce 100644 --- a/exercises/18_iterators/iterators3.rs +++ b/exercises/18_iterators/iterators3.rs @@ -9,7 +9,7 @@ // Execute `rustlings hint iterators3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE +// https://doc.rust-lang.org/stable/book/ch13-04-performance.html #[derive(Debug, PartialEq, Eq)] pub enum DivisionError { @@ -23,26 +23,38 @@ pub struct NotDivisibleError { divisor: i32, } -// Calculate `a` divided by `b` if `a` is evenly divisible by `b`. -// Otherwise, return a suitable error. +/// Calculate `a` divided by `b` if `a` is evenly divisible by `b`. +/// Otherwise, return a suitable error. pub fn divide(a: i32, b: i32) -> Result { - todo!(); + match b { + 0 => Err(DivisionError::DivideByZero), + _ if a % b != 0 => Err(DivisionError::NotDivisible(NotDivisibleError { + dividend: a, + divisor: b, + })), + _ => Ok(a / b), + } } -// Complete the function and return a value of the correct type so the test -// passes. -// Desired output: Ok([1, 11, 1426, 3]) -fn result_with_list() -> () { +// Complete the function and return a value of the correct type so the test passes. +/// Desired output: Ok([1, 11, 1426, 3]) +fn result_with_list() -> Result, DivisionError> { let numbers = vec![27, 297, 38502, 81]; - let division_results = numbers.into_iter().map(|n| divide(n, 27)); + + // Force division_results to be a Result, DivisionError> + let division_results: Result, DivisionError> = numbers + .into_iter() // turns the numbers into an iterator + .map(|n| divide(n, 27)) // divides each number by 27 + .collect(); // converts the iterator into a type as specified by the type annotation + return division_results; } -// Complete the function and return a value of the correct type so the test -// passes. -// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)] -fn list_of_results() -> () { +// Complete the function and return a value of the correct type so the test passes. +/// Desired output: [Ok(1), Ok(11), Ok(1426), Ok(3)] +fn list_of_results() -> Vec> { let numbers = vec![27, 297, 38502, 81]; - let division_results = numbers.into_iter().map(|n| divide(n, 27)); + let division_results = numbers.into_iter().map(|n| divide(n, 27)).collect(); + return division_results; } #[cfg(test)] diff --git a/exercises/18_iterators/iterators4.rs b/exercises/18_iterators/iterators4.rs index 3c0724e9..22e91d6c 100644 --- a/exercises/18_iterators/iterators4.rs +++ b/exercises/18_iterators/iterators4.rs @@ -3,10 +3,10 @@ // Execute `rustlings hint iterators4` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE +// https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.fold pub fn factorial(num: u64) -> u64 { - // Complete this function to return the factorial of num + /// Return the factorial of num // Do not use: // - early returns (using the `return` keyword explicitly) // Try not to use: @@ -14,7 +14,8 @@ pub fn factorial(num: u64) -> u64 { // - additional variables // For an extra challenge, don't use: // - recursion - // Execute `rustlings hint iterators4` for hints. + // Fold is a higher order function that applies a function to each element of an iterator, passing the result of the function to the next element. + (1..=num).fold(1, |acc, x| acc * x) } #[cfg(test)] diff --git a/exercises/18_iterators/iterators5.rs b/exercises/18_iterators/iterators5.rs index a062ee4c..2540091a 100644 --- a/exercises/18_iterators/iterators5.rs +++ b/exercises/18_iterators/iterators5.rs @@ -11,8 +11,6 @@ // Execute `rustlings hint iterators5` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE - use std::collections::HashMap; #[derive(Clone, Copy, PartialEq, Eq)] @@ -22,6 +20,7 @@ enum Progress { Complete, } +/// Count the number of exercises with a given progress. fn count_for(map: &HashMap, value: Progress) -> usize { let mut count = 0; for val in map.values() { @@ -32,12 +31,15 @@ fn count_for(map: &HashMap, value: Progress) -> usize { count } +/// Count the number of exercises with a given progress using iterators. +/// https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter fn count_iterator(map: &HashMap, value: Progress) -> usize { // map is a hashmap with String keys and Progress values. // map = { "variables1": Complete, "from_str": None, ... } - todo!(); + map.values().filter(|&val| val == &value).count() } +/// Count the number of exercises with a given progress in a collection of progress maps. fn count_collection_for(collection: &[HashMap], value: Progress) -> usize { let mut count = 0; for map in collection { @@ -50,11 +52,15 @@ fn count_collection_for(collection: &[HashMap], value: Progres count } +/// Count the number of exercises with a given progress in a collection of progress maps using iterators. fn count_collection_iterator(collection: &[HashMap], value: Progress) -> usize { // collection is a slice of hashmaps. // collection = [{ "variables1": Complete, "from_str": None, ... }, // { "variables2": Complete, ... }, ... ] - todo!(); + collection + .iter() // iterate over the collection + .map(|map| count_iterator(map, value)) + .sum() } #[cfg(test)]