iterators5.rs (4481B)
1 // Let's define a simple model to track Rustlings' exercise progress. Progress 2 // will be modelled using a hash map. The name of the exercise is the key and 3 // the progress is the value. Two counting functions were created to count the 4 // number of exercises with a given progress. Recreate this counting 5 // functionality using iterators. Try to not use imperative loops (for/while). 6 7 use std::collections::HashMap; 8 9 #[derive(Clone, Copy, PartialEq, Eq)] 10 enum Progress { 11 None, 12 Some, 13 Complete, 14 } 15 16 fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize { 17 let mut count = 0; 18 for val in map.values() { 19 if *val == value { 20 count += 1; 21 } 22 } 23 count 24 } 25 26 // TODO: Implement the functionality of `count_for` but with an iterator instead 27 // of a `for` loop. 28 fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize { 29 // `map` is a hash map with `String` keys and `Progress` values. 30 // map = { "variables1": Complete, "from_str": None, … } 31 } 32 33 fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize { 34 let mut count = 0; 35 for map in collection { 36 for val in map.values() { 37 if *val == value { 38 count += 1; 39 } 40 } 41 } 42 count 43 } 44 45 // TODO: Implement the functionality of `count_collection_for` but with an 46 // iterator instead of a `for` loop. 47 fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Progress) -> usize { 48 // `collection` is a slice of hash maps. 49 // collection = [{ "variables1": Complete, "from_str": None, … }, 50 // { "variables2": Complete, … }, … ] 51 } 52 53 fn main() { 54 // You can optionally experiment here. 55 } 56 57 #[cfg(test)] 58 mod tests { 59 use super::*; 60 61 fn get_map() -> HashMap<String, Progress> { 62 use Progress::*; 63 64 let mut map = HashMap::new(); 65 map.insert(String::from("variables1"), Complete); 66 map.insert(String::from("functions1"), Complete); 67 map.insert(String::from("hashmap1"), Complete); 68 map.insert(String::from("arc1"), Some); 69 map.insert(String::from("as_ref_mut"), None); 70 map.insert(String::from("from_str"), None); 71 72 map 73 } 74 75 fn get_vec_map() -> Vec<HashMap<String, Progress>> { 76 use Progress::*; 77 78 let map = get_map(); 79 80 let mut other = HashMap::new(); 81 other.insert(String::from("variables2"), Complete); 82 other.insert(String::from("functions2"), Complete); 83 other.insert(String::from("if1"), Complete); 84 other.insert(String::from("from_into"), None); 85 other.insert(String::from("try_from_into"), None); 86 87 vec![map, other] 88 } 89 90 #[test] 91 fn count_complete() { 92 let map = get_map(); 93 assert_eq!(count_iterator(&map, Progress::Complete), 3); 94 } 95 96 #[test] 97 fn count_some() { 98 let map = get_map(); 99 assert_eq!(count_iterator(&map, Progress::Some), 1); 100 } 101 102 #[test] 103 fn count_none() { 104 let map = get_map(); 105 assert_eq!(count_iterator(&map, Progress::None), 2); 106 } 107 108 #[test] 109 fn count_complete_equals_for() { 110 let map = get_map(); 111 let progress_states = [Progress::Complete, Progress::Some, Progress::None]; 112 for progress_state in progress_states { 113 assert_eq!( 114 count_for(&map, progress_state), 115 count_iterator(&map, progress_state), 116 ); 117 } 118 } 119 120 #[test] 121 fn count_collection_complete() { 122 let collection = get_vec_map(); 123 assert_eq!( 124 count_collection_iterator(&collection, Progress::Complete), 125 6, 126 ); 127 } 128 129 #[test] 130 fn count_collection_some() { 131 let collection = get_vec_map(); 132 assert_eq!(count_collection_iterator(&collection, Progress::Some), 1); 133 } 134 135 #[test] 136 fn count_collection_none() { 137 let collection = get_vec_map(); 138 assert_eq!(count_collection_iterator(&collection, Progress::None), 4); 139 } 140 141 #[test] 142 fn count_collection_equals_for() { 143 let collection = get_vec_map(); 144 let progress_states = [Progress::Complete, Progress::Some, Progress::None]; 145 146 for progress_state in progress_states { 147 assert_eq!( 148 count_collection_for(&collection, progress_state), 149 count_collection_iterator(&collection, progress_state), 150 ); 151 } 152 } 153 }