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++, dictionary in Python or an associative array in other languages.
This is the other data structure that we’ve been talking about before, when talking about Vecs.
Further information
Rustlings
hashmaps1
// hashmaps1.rs // A basket of fruits in the form of a hash map needs to be defined. // The key represents the name of the fruit and the value represents // how many of that particular fruit is in the basket. You have to put // at least three different types of fruits (e.g apple, banana, mango) // in the basket and the total count of all the fruits should be at // least five. // // Make me compile and pass the tests! // // Execute `rustlings hint hashmaps1` or use the `hint` watch subcommand for a hint. // I AM NOT DONE use std::collections::HashMap; fn fruit_basket() -> HashMap<String, u32> { let mut basket = // TODO: declare your hash map here. // Two bananas are already given for you :) basket.insert(String::from("banana"), 2); // TODO: Put more fruits in your basket here. basket } #[cfg(test)] mod tests { use super::*; #[test] fn at_least_three_types_of_fruits() { let basket = fruit_basket(); assert!(basket.len() >= 3); } #[test] fn at_least_five_fruits() { let basket = fruit_basket(); assert!(basket.values().sum::<u32>() >= 5); } }
hashmaps2
// hashmaps2.rs // A basket of fruits in the form of a hash map is given. The key // represents the name of the fruit and the value represents how many // of that particular fruit is in the basket. You have to put *MORE // THAN 11* fruits in the basket. Three types of fruits - Apple (4), // Mango (2) and Lychee (5) are already given in the basket. You are // not allowed to insert any more of these fruits! // // Make me pass the tests! // // Execute `rustlings hint hashmaps2` or use the `hint` watch subcommand for a hint. // I AM NOT DONE use std::collections::HashMap; #[derive(Hash, PartialEq, Eq)] enum Fruit { Apple, Banana, Mango, Lychee, Pineapple, } fn fruit_basket(basket: &mut HashMap<Fruit, u32>) { let fruit_kinds = vec![ Fruit::Apple, Fruit::Banana, Fruit::Mango, Fruit::Lychee, Fruit::Pineapple, ]; for fruit in fruit_kinds { // TODO: Put new fruits if not already present. Note that you // are not allowed to put any type of fruit that's already // present! } } #[cfg(test)] mod tests { use super::*; fn get_fruit_basket() -> HashMap<Fruit, u32> { let mut basket = HashMap::<Fruit, u32>::new(); basket.insert(Fruit::Apple, 4); basket.insert(Fruit::Mango, 2); basket.insert(Fruit::Lychee, 5); basket } #[test] fn test_given_fruits_are_not_modified() { let mut basket = get_fruit_basket(); fruit_basket(&mut basket); assert_eq!(*basket.get(&Fruit::Apple).unwrap(), 4); assert_eq!(*basket.get(&Fruit::Mango).unwrap(), 2); assert_eq!(*basket.get(&Fruit::Lychee).unwrap(), 5); } #[test] fn at_least_five_types_of_fruits() { let mut basket = get_fruit_basket(); fruit_basket(&mut basket); let count_fruit_kinds = basket.len(); assert!(count_fruit_kinds >= 5); } #[test] fn greater_than_eleven_fruits() { let mut basket = get_fruit_basket(); fruit_basket(&mut basket); let count = basket.values().sum::<u32>(); assert!(count > 11); } }
hashmaps3
// hashmaps3.rs // A list of scores (one per line) of a soccer match is given. Each line // is of the form : // <team_1_name>,<team_2_name>,<team_1_goals>,<team_2_goals> // Example: England,France,4,2 (England scored 4 goals, France 2). // You have to build a scores table containing the name of the team, goals // the team scored, and 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! // Execute `rustlings hint hashmaps3` or use the `hint` watch subcommand for a hint. // I AM NOT DONE use std::collections::HashMap; // A structure to store team name and its goal details. struct Team { name: String, goals_scored: u8, goals_conceded: u8, } fn build_scores_table(results: String) -> HashMap<String, Team> { // The name of the team is the key and its associated struct is the value. let mut scores: HashMap<String, Team> = HashMap::new(); for r in results.lines() { let v: Vec<&str> = r.split(',').collect(); let team_1_name = v[0].to_string(); 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 // current line. Keep in mind that goals scored by team_1 // will be the number of goals conceded from team_2, and similarly // goals scored by team_2 will be the number of goals conceded by // team_1. } scores } #[cfg(test)] mod tests { use super::*; fn get_results() -> String { let results = "".to_string() + "England,France,4,2\n" + "France,Italy,3,1\n" + "Poland,Spain,2,0\n" + "Germany,England,2,1\n"; results } #[test] fn build_scores() { let scores = build_scores_table(get_results()); let mut keys: Vec<&String> = scores.keys().collect(); keys.sort(); assert_eq!( keys, vec!["England", "France", "Germany", "Italy", "Poland", "Spain"] ); } #[test] fn validate_team_score_1() { let scores = build_scores_table(get_results()); let team = scores.get("England").unwrap(); assert_eq!(team.goals_scored, 5); assert_eq!(team.goals_conceded, 4); } #[test] fn validate_team_score_2() { let scores = build_scores_table(get_results()); let team = scores.get("Spain").unwrap(); assert_eq!(team.goals_scored, 0); assert_eq!(team.goals_conceded, 2); } }