Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions exercises/standard_library_types/iterators5.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
// iterators5.rs

// Let's define a simple model to track Rustlings exercise progress. Progress
// will be modelled using a hash map. The name of the exercise is the key and
// the progress is the value. Two counting functions were created to count the
// number of exercises with a given progress. These counting functions use
// imperative style for loops. Recreate this counting functionality using
// iterators. Only the two iterator methods (count_iterator and
// count_collection_iterator) need to be modified.
// Execute `rustlings hint
// iterators5` for hints.
//
// Make the code compile and the tests pass.

// I AM NOT DONE

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, I would leave comments somewhere in this exercise with notes that explain:

  • What a "stack" is (aka a vec of hashmaps)
  • That you probably shouldn't touch the _for methods, but rather implement the iterative version in the other methods
  • A delineator above the tests module telling the user not to touch what's below it

use std::collections::HashMap;

#[derive(PartialEq, Eq)]
enum Progress {
None,
Some,
Complete,
}

fn count_for(map: &HashMap<String, Progress>, value: Progress) -> usize {
let mut count = 0;
for val in map.values() {
if val == &value {
count += 1;
}
}
count
}

fn count_iterator(map: &HashMap<String, Progress>, value: Progress) -> usize {
// map is a hashmap with String keys and Progress values.
// map = { "variables1": Complete, "from_str": None, ... }
}

fn count_collection_for(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
let mut count = 0;
for map in collection {
for val in map.values() {
if val == &value {
count += 1;
}
}
}
count
}

fn count_collection_iterator(collection: &[HashMap<String, Progress>], value: Progress) -> usize {
// collection is a slice of hashmaps.
// collection = [{ "variables1": Complete, "from_str": None, ... },
// { "variables2": Complete, ... }, ... ]
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn count_complete() {
let map = get_map();
assert_eq!(3, count_iterator(&map, Progress::Complete));
}

#[test]
fn count_equals_for() {
let map = get_map();
assert_eq!(
count_for(&map, Progress::Complete),
count_iterator(&map, Progress::Complete)
);
}

#[test]
fn count_collection_complete() {
let collection = get_vec_map();
assert_eq!(
6,
count_collection_iterator(&collection, Progress::Complete)
);
}

#[test]
fn count_collection_equals_for() {
let collection = get_vec_map();
assert_eq!(
count_collection_for(&collection, Progress::Complete),
count_collection_iterator(&collection, Progress::Complete)
);
}

fn get_map() -> HashMap<String, Progress> {
use Progress::*;

let mut map = HashMap::new();
map.insert(String::from("variables1"), Complete);
map.insert(String::from("functions1"), Complete);
map.insert(String::from("hashmap1"), Complete);
map.insert(String::from("arc1"), Some);
map.insert(String::from("as_ref_mut"), None);
map.insert(String::from("from_str"), None);

map
}

fn get_vec_map() -> Vec<HashMap<String, Progress>> {
use Progress::*;

let map = get_map();

let mut other = HashMap::new();
other.insert(String::from("variables2"), Complete);
other.insert(String::from("functions2"), Complete);
other.insert(String::from("if1"), Complete);
other.insert(String::from("from_into"), None);
other.insert(String::from("try_from_into"), None);

vec![map, other]
}
}
18 changes: 17 additions & 1 deletion info.toml
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ Step 2 & step 2.1:
Very similar to the lines above and below. You've got this!
Step 3:
An iterator goes through all elements in a collection, but what if we've run out of
elements? What should we expect here? If you're stuck, take a look at
elements? What should we expect here? If you're stuck, take a look at
https://doc.rust-lang.org/std/iter/trait.Iterator.html for some ideas.
"""

Expand Down Expand Up @@ -741,6 +741,22 @@ a mutable variable. Or, you might write code utilizing recursion
and a match clause. In Rust you can take another functional
approach, computing the factorial elegantly with ranges and iterators."""

[[exercises]]
name = "iterators5"
path = "exercises/standard_library_types/iterators5.rs"
mode = "test"
hint = """
The documentation for the std::iter::Iterator trait contains numerous methods
that would be helpful here.

Return 0 from count_collection_iterator to make the code compile in order to
test count_iterator.

The collection variable in count_collection_iterator is a slice of HashMaps. It
needs to be converted into an iterator in order to use the iterator methods.

The fold method can be useful in the count_collection_iterator function."""

# THREADS

[[exercises]]
Expand Down