Skip to Content

Mapa

Podstawowe operacje

  1. Mapę tworzymy za pomocą metody new dla typu HashMap
    let mut map = HashMap::new();
  2. Dodawanie i usuwanie elementów do mapy za pomocą metod insert i remove:
    map.insert(String::from("world"), 1); map.insert(String::from("rust"), 2); map.remove("world");
  3. Pobieranie wartości za pomocą metody get:
    let cnt : Option<&i32> = map.get("rust"); // returns an optional reference to a value in the map
  4. Iteracja po elementach mapy (parach klucz-wartość) odbywa się według zasad omówionych przy okazji wektora:
    for (text, number) in &map { // immutable borrow println!("{} has {} occurrences", text, number); }

Ćwiczenie - statystyka wyrazów

  1. Napisz funkcję words_stat, która przyjmuje listę wyrazów i zwraca mapę, która posiada statystykę wystąpień poszczególnych wyrazów.
    fn words_stats(words: &Vec<String>) -> HashMap<String, i32> { todo!(); }
  2. Sprawdź statystyki utworu Pan Tadeusz z wykorzystaniem następującego kodu:
    fn hash_map_words_stats_poem() { let response = reqwest::blocking::get("https://wolnelektury.pl/media/book/txt/pan-tadeusz.txt").expect("Cannot get poem from a given URL"); let poem = response.text().unwrap(); let stats = words_stats(&split_to_words(&poem)); let sorted_stats = sort_stats(&stats); println!("{:?}", &sorted_stats[..20]); } fn split_to_words(s: &str) -> Vec<String> { let mut words = Vec::new(); for word in s.split_whitespace() { let unified_word = word.trim_matches(|c| char::is_ascii_punctuation(&c)).to_lowercase(); words.push(unified_word); } words } fn sort_stats(stats : &HashMap<String, i32>) -> Vec<(&str, i32)> { let mut sorted_stats : Vec<(&str, i32)> = Vec::new(); for (word, count) in stats.iter() { sorted_stats.push((word, *count)); } sorted_stats.sort_by(|(_, c1), (_, c2)| c2.partial_cmp(c1).expect("FAILED")); sorted_stats }

Typ Entry

  1. Rust definiuje typ Entry, który jest widokiem na elementy w mapie. Reprezentuje on element posiadający wartość (Occupied) oraz element pusty (Vacant):
    pub enum Entry<'a, K: 'a, V: 'a> { Occupied(OccupiedEntry<'a, K, V>), Vacant(VacantEntry<'a, K, V>), }
  2. Aby uzyskać widok Entry dla danego klucza, wykorzystujemy metodę entry:
    let entry = map.entry("rust");
  3. Typ Entry definiuje szereg metod, które pozwalają w przyjazny sposób obsłużyć sytuacje, w których nie jesteśmy pewni czy dana wartość istnieje w mapie czy nie. Przykładem jest tutaj metoda or_insert, a poniżej jej zastosowanie w funkcji zliczającej wyrazy:
    let count : &i32 = map.entry(word.to_owned()).or_insert(0); *count += 1;
  4. Metoda or_insert zwraca mutowalną pożyczkę, a więc może być wykorzystana po lewej stronie przypisania, wtedy nasz kod wygląda jeszcze krócej:
    map.entry(word.to_owned()).or_insert(0) += 1;
  5. Inna metoda and_modify pozwala z wykorzystaniem domknięć (o których będzie za chwilę) zdefiniować przepis na modyfikację elementu, zanim nastąpi ewentualne dodanie nowych wartości. Skutek wykonania poniższego kodu jest taki sam jak w poprzednim przykładzie:
    map.entry(word.to_owned()).and_modify(|counter| *counter += 1).or_insert(1);

Ćwiczenie

  1. Zmodyfikuj przykład liczenia wyrazów, tak aby wykorzystać typ Entry.
Last updated on