diff --git a/solutions/collections/Hashmap.md b/solutions/collections/Hashmap.md index e69de29..7b25aae 100644 --- a/solutions/collections/Hashmap.md +++ b/solutions/collections/Hashmap.md @@ -0,0 +1,73 @@ +1. +```rust +// FILL in the blanks and FIX the erros +use std::collections::HashMap; +fn main() { + let mut scores = HashMap::new(); + scores.insert("Sunface", 98); + scores.insert("Daniel", 95); + scores.insert("Ashley", 69); + scores.insert("Katie", 58); + + // get returns a Option<&V> + let score = scores.get("Sunface"); + assert_eq!(score, Some(&98)); + + if scores.contains_key("Daniel") { + // indexing return a value V + let score = scores["Daniel"]; + assert_eq!(score, 95); + scores.remove("Daniel"); + } + + assert_eq!(scores.len(), 3); + + for (name, score) in scores { + println!("The score of {} is {}", name, score) + } +} +``` + +2. +```rust +use std::collections::HashMap; +fn main() { + let teams = [ + ("Chinese Team", 100), + ("American Team", 10), + ("France Team", 50), + ]; + + let mut teams_map1 = HashMap::new(); + for team in &teams { + teams_map1.insert(team.0, team.1); + } + + let teams_map2: HashMap<_,_> = teams.into_iter().collect(); + + assert_eq!(teams_map1, teams_map2); + + println!("Success!") +} +``` + +```rust +use std::{collections::HashMap}; +fn main() { + let teams = [ + ("Chinese Team", 100), + ("American Team", 10), + ("France Team", 50), + ]; + + let mut teams_map1 = HashMap::new(); + for team in &teams { + teams_map1.insert(team.0, team.1); + } + + let teams_map2 = HashMap::from(teams); + assert_eq!(teams_map1, teams_map2); + + println!("Success!") +} +``` \ No newline at end of file diff --git a/src/collections/hashmap.md b/src/collections/hashmap.md index 2f76ee4..c370064 100644 --- a/src/collections/hashmap.md +++ b/src/collections/hashmap.md @@ -1,7 +1,5 @@ # HashMap -Where vectors store values by an integer index, HashMaps store values by key. `HashMap` keys can be booleans, integers, strings, or any other type that implements the Eq and Hash traits. - -It is also a hash map implemented with quadratic probing and SIMD lookup. By default, `HashMap` uses a hashing algorithm selected to provide resistance against HashDoS attacks. +Where vectors store values by an integer index, HashMaps store values by key. It is a hash map implemented with quadratic probing and SIMD lookup. By default, `HashMap` uses a hashing algorithm selected to provide resistance against HashDoS attacks. The default hashing algorithm is currently `SipHash 1-3`, though this is subject to change at any point in the future. While its performance is very competitive for medium sized keys, other hashing algorithms will outperform it for small keys such as integers as well as large keys such as long strings, though those algorithms will typically not protect against attacks such as HashDoS. @@ -9,12 +7,43 @@ The hash table implementation is a Rust port of Google’s [SwissTable](https:// ### Basic Operations +1. 🌟🌟 + +```rust,editbale +// FILL in the blanks and FIX the erros +use std::collections::HashMap; +fn main() { + let mut scores = HashMap::new(); + scores.insert("Sunface", 98); + scores.insert("Daniel", 95); + scores.insert("Ashley", 69.0); + scores.insert("Katie", "58"); + + // get returns a Option<&V> + let score = scores.get("Sunface"); + assert_eq!(score, Some(98)); + + if scores.contains_key("Daniel") { + // indexing return a value V + let score = scores["Daniel"]; + assert_eq!(score, __); + scores.remove("Daniel"); + } + + assert_eq!(scores.len(), __); + + for (name, score) in scores { + println!("The score of {} is {}", name, score) + } +} +``` 2. 🌟🌟 ```rust,editable + use std::collections::HashMap; fn main() { - let teams = vec![ + let teams = [ ("Chinese Team", 100), ("American Team", 10), ("France Team", 50), @@ -25,12 +54,56 @@ fn main() { teams_map1.insert(team.0, team.1); } - // IMPLEMENT team_map2 with method collect + // IMPLEMENT team_map2 in two ways + // tips: one of the approaches is to use `collect` method let teams_map2... assert_eq!(teams_map1, teams_map2); + + println!("Success!") } ``` +3. 🌟🌟 +```rust,editable + +// FILL in the blanks +use std::collections::HashMap; +fn main() { + // type inference lets us omit an explicit type signature (which + // would be `HashMap<&str, u8>` in this example). + let mut player_stats = HashMap::new(); + + // insert a key only if it doesn't already exist + player_stats.entry("health").or_insert(100); + + assert_eq!(player_stats["health"], __); + + // insert a key using a function that provides a new value only if it + // doesn't already exist + player_stats.entry("health").or_insert_with(random_stat_buff); + assert_eq!(player_stats["health"], __); + + // Ensures a value is in the entry by inserting the default if empty, and returns + // a mutable reference to the value in the entry. + let health = player_stats.entry("health").or_insert(50); + assert_eq!(health, __); + *health -= 50; + assert_eq!(*health, __); + + println!("Success!") +} + +fn random_stat_buff() -> u8 { + // could actually return some random value here - let's just return + // some fixed value for now + 42 +} +``` + +### Requirements of HashMap key + `HashMap` keys can be booleans, integers, strings, or any other type that implements the Eq and Hash traits. + + ### Capacity Like vectors, HashMaps are growable, but HashMaps can also shrink themselves when they have excess space. You can create a HashMap with a certain starting capacity using HashMap::with_capacity(uint), or use HashMap::new() to get a HashMap with a default initial capacity (recommended). \ No newline at end of file