From 28e750312221cbdeacae290ce19898bc46b4781c Mon Sep 17 00:00:00 2001 From: My Chiffon Nguyen Date: Fri, 21 Jun 2024 16:11:31 +0200 Subject: [PATCH] 11 Hash map ~ Python dict. See README.md --- exercises/11_hashmaps/README.md | 43 +++++++++++++++++++++++++++--- exercises/11_hashmaps/hashmaps1.rs | 8 +++--- exercises/11_hashmaps/hashmaps2.rs | 16 ++++++++--- exercises/11_hashmaps/hashmaps3.rs | 34 +++++++++++++++++++---- 4 files changed, 86 insertions(+), 15 deletions(-) diff --git a/exercises/11_hashmaps/README.md b/exercises/11_hashmaps/README.md index 80ec1441..52b0fdba 100644 --- a/exercises/11_hashmaps/README.md +++ b/exercises/11_hashmaps/README.md @@ -1,12 +1,49 @@ # Hashmaps -A *hash map* allows you to associate a value with a particular key. -You may also know this by the names [*unordered map* in C++](https://en.cppreference.com/w/cpp/container/unordered_map), -[*dictionary* in Python](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) or an *associative array* in other languages. +A _hash map_ allows you to associate a value with a particular key. +You may also know this by the names [_unordered map_ in C++](https://en.cppreference.com/w/cpp/container/unordered_map), +[_dictionary_ in Python](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) or an _associative array_ in other languages. This is the other data structure that we've been talking about before, when talking about Vecs. +## Syntax + +Create, insert values into a hash map, and get a value from a hash map: + +```rust +use std::collections::HashMap; + +fn main() { + let mut scores = HashMap::new(); + + scores.insert(String::from("Blue"), 10); + scores.insert(String::from("Yellow"), 50); + + let team_name = String::from("Blue"); + let score = scores.get(&team_name); + + println!("{:?}", score); +} +``` + +Update a value in a hash map: + +```rust +use std::collections::HashMap; + +fn main() { + let mut scores = HashMap::new(); + + scores.insert(String::from("Blue"), 10); + + // Add 10 to the value of the key "Blue"; or insert the key with a value of 10 if it doesn't exist + scores.entry(String::from("Blue")).and_modify(|v| *v += 10).or_insert(10); + + println!("{:?}", scores); +} +``` + ## Further information - [Storing Keys with Associated Values in Hash Maps](https://doc.rust-lang.org/book/ch08-03-hash-maps.html) diff --git a/exercises/11_hashmaps/hashmaps1.rs b/exercises/11_hashmaps/hashmaps1.rs index 02f4725e..a481d28d 100644 --- a/exercises/11_hashmaps/hashmaps1.rs +++ b/exercises/11_hashmaps/hashmaps1.rs @@ -11,17 +11,19 @@ // Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE +// https://doc.rust-lang.org/book/ch08-03-hash-maps.html#creating-a-new-hash-map use std::collections::HashMap; fn fruit_basket() -> HashMap { - let mut basket = // TODO: declare your hash map here. + let mut basket = HashMap::new(); // Two bananas are already given for you :) basket.insert(String::from("banana"), 2); - // TODO: Put more fruits in your basket here. + // Add at least three different types of fruits + basket.insert(String::from("apple"), 1); + basket.insert(String::from("mango"), 2); basket } diff --git a/exercises/11_hashmaps/hashmaps2.rs b/exercises/11_hashmaps/hashmaps2.rs index a5925690..2e7f8139 100644 --- a/exercises/11_hashmaps/hashmaps2.rs +++ b/exercises/11_hashmaps/hashmaps2.rs @@ -14,7 +14,7 @@ // Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE +// https://doc.rust-lang.org/book/ch08-03-hash-maps.html#adding-a-key-and-value-only-if-a-key-isnt-present use std::collections::HashMap; @@ -37,9 +37,17 @@ fn fruit_basket(basket: &mut HashMap) { ]; for fruit in fruit_kinds { - // TODO: Insert new fruits if they are not already present in the - // basket. Note that you are not allowed to put any type of fruit that's - // already present! + // Insert new fruits if they are not already present in the + // basket. Note that you are not allowed to put any type of fruit that's already present! + // Method 1 + /* + if !basket.contains_key(&fruit) { + basket.insert(fruit, 1); + } + */ + // Method 2 + basket.entry(fruit).or_insert(1); + } } diff --git a/exercises/11_hashmaps/hashmaps3.rs b/exercises/11_hashmaps/hashmaps3.rs index 8d9236df..359a837f 100644 --- a/exercises/11_hashmaps/hashmaps3.rs +++ b/exercises/11_hashmaps/hashmaps3.rs @@ -5,9 +5,9 @@ // Example: England,France,4,2 (England scored 4 goals, France 2). // // You have to build a scores table containing the name of the team, the total -// number of goals the team scored, and the total number of goals the team -// conceded. One approach to build the scores table is to use a Hashmap. -// The solution is partially written to use a Hashmap, +// number of goals the team scored, and the total number of goals the team +// conceded. One approach to build the scores table is to use a Hashmap. +// The solution is partially written to use a Hashmap, // complete it to pass the test. // // Make me pass the tests! @@ -15,7 +15,7 @@ // Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a // hint. -// I AM NOT DONE +// https://doc.rust-lang.org/book/ch08-03-hash-maps.html#updating-a-value-based-on-the-old-value use std::collections::HashMap; @@ -35,12 +35,36 @@ fn build_scores_table(results: String) -> HashMap { let team_1_score: u8 = v[2].parse().unwrap(); let team_2_name = v[1].to_string(); let team_2_score: u8 = v[3].parse().unwrap(); - // TODO: Populate the scores table with details extracted from the + // Populate the scores table with details extracted from the // current line. Keep in mind that goals scored by team_1 // will be the number of goals conceded by team_2, and similarly // goals scored by team_2 will be the number of goals conceded by // team_1. + // If scores table does not contain the team, insert a new entry and scores. Otherwise, update the scores. + scores + .entry(team_1_name.clone()) + .and_modify(|e| { + e.goals_scored += team_1_score; + e.goals_conceded += team_2_score; + }) + .or_insert(Team { + goals_scored: team_1_score, + goals_conceded: team_2_score, + }); + + // Update the scores for team 2 + scores + .entry(team_2_name.clone()) + .and_modify(|e| { + e.goals_scored += team_2_score; + e.goals_conceded += team_1_score; + }) + .or_insert(Team { + goals_scored: team_2_score, + goals_conceded: team_1_score, + }); } + scores }