763 lines
18 KiB
Markdown
763 lines
18 KiB
Markdown
# HashMap — krok za krokom
|
|
|
|
Každá kapitola: prečítaj, pozri príklady, urob úlohy. Až potom choď ďalej.
|
|
Riešenia sú na konci, číslované.
|
|
|
|
```rust
|
|
use std::collections::HashMap; // toto treba vždy
|
|
```
|
|
|
|
---
|
|
|
|
## Kapitola 1: Vytvorenie a insert
|
|
|
|
HashMap je kolekcia párov kľúč → hodnota. Kľúč je unikátny.
|
|
|
|
```rust
|
|
let mut mapa: HashMap<String, i32> = HashMap::new();
|
|
|
|
mapa.insert("Anna".to_string(), 25);
|
|
mapa.insert("Boris".to_string(), 30);
|
|
// mapa = {"Anna": 25, "Boris": 30}
|
|
|
|
// insert na existujúci kľúč PREPÍŠE hodnotu a vráti starú
|
|
let stara = mapa.insert("Anna".to_string(), 26);
|
|
// stara = Some(25), mapa = {"Anna": 26, "Boris": 30}
|
|
|
|
// insert na nový kľúč vráti None
|
|
let stara = mapa.insert("Cyril".to_string(), 22);
|
|
// stara = None
|
|
```
|
|
|
|
### Úlohy 1
|
|
|
|
**1a.** Vytvor HashMap kde kľúče sú mená ovocia (String) a hodnoty sú ceny (f64). Vlož 3 ovocia.
|
|
|
|
**1b.** Čo vráti posledný insert? Napíš kód a over:
|
|
```rust
|
|
let mut m = HashMap::new();
|
|
m.insert("x", 1);
|
|
m.insert("y", 2);
|
|
let vysledok = m.insert("x", 99);
|
|
println!("{:?}", vysledok);
|
|
```
|
|
|
|
**1c.** Vytvor HashMap z vektora dvojíc pomocou `.collect()`:
|
|
```rust
|
|
let data = vec![("sk", "Slovensko"), ("cz", "Česko"), ("pl", "Poľsko")];
|
|
// tvoj kód → HashMap<&str, &str>
|
|
```
|
|
|
|
---
|
|
|
|
## Kapitola 2: Čítanie — get, contains_key, len
|
|
|
|
```rust
|
|
let mut mapa = HashMap::new();
|
|
mapa.insert("Anna".to_string(), 25);
|
|
mapa.insert("Boris".to_string(), 30);
|
|
|
|
// get — vráti Option<&V>
|
|
let vek = mapa.get("Anna"); // Some(&25)
|
|
let vek = mapa.get("Cyril"); // None
|
|
|
|
// contains_key — vráti bool
|
|
let je_tam = mapa.contains_key("Anna"); // true
|
|
let je_tam = mapa.contains_key("Cyril"); // false
|
|
|
|
// len — počet párov
|
|
let pocet = mapa.len(); // 2
|
|
|
|
// is_empty
|
|
let prazdna = mapa.is_empty(); // false
|
|
```
|
|
|
|
**Dôležité:** Nikdy nepoužívaj `mapa["Anna"]` — ak kľúč neexistuje, program spadne. Vždy `.get()`.
|
|
|
|
### Úlohy 2
|
|
|
|
**2a.** Máš mapu ovocia z úlohy 1a. Napíš kód, ktorý:
|
|
- Vypíše cenu jablka ak existuje
|
|
- Vypíše "Nemáme" ak neexistuje
|
|
Použi `if let` s `.get()`.
|
|
|
|
**2b.** Napíš funkciu:
|
|
```rust
|
|
fn je_v_mape(mapa: &HashMap<String, i32>, kluc: &str) -> bool
|
|
```
|
|
Použi `contains_key`.
|
|
|
|
**2c.** Čo vypíše? Tipni, potom over:
|
|
```rust
|
|
let mut m: HashMap<&str, i32> = HashMap::new();
|
|
m.insert("a", 1);
|
|
println!("{:?}", m.get("a"));
|
|
println!("{:?}", m.get("b"));
|
|
println!("{}", m.len());
|
|
println!("{}", m.contains_key("a"));
|
|
println!("{}", m.contains_key("b"));
|
|
```
|
|
|
|
---
|
|
|
|
## Kapitola 3: Mazanie — remove, clear
|
|
|
|
```rust
|
|
let mut mapa = HashMap::new();
|
|
mapa.insert("Anna".to_string(), 25);
|
|
mapa.insert("Boris".to_string(), 30);
|
|
|
|
// remove — vráti Option<V> (hodnotu, nie referenciu)
|
|
let odstraneny = mapa.remove("Anna");
|
|
// odstraneny = Some(25), mapa = {"Boris": 30}
|
|
|
|
let odstraneny = mapa.remove("Cyril");
|
|
// odstraneny = None (neexistoval)
|
|
|
|
// clear — vymaže všetko
|
|
mapa.clear();
|
|
// mapa = {}
|
|
```
|
|
|
|
### Úlohy 3
|
|
|
|
**3a.** Vytvor mapu s 3 položkami. Odstráň jednu. Vypíš čo `remove` vrátil. Vypíš veľkosť mapy.
|
|
|
|
**3b.** Napíš funkciu:
|
|
```rust
|
|
fn odstran_ak_existuje(mapa: &mut HashMap<String, i32>, kluc: &str) -> Option<i32>
|
|
```
|
|
Ak kľúč existuje, odstráň ho a vráť hodnotu. Ak nie, vráť None. (Hint: `remove` presne toto robí.)
|
|
|
|
---
|
|
|
|
## Kapitola 4: Iterácia
|
|
|
|
```rust
|
|
let mut mapa = HashMap::new();
|
|
mapa.insert("Anna".to_string(), 25);
|
|
mapa.insert("Boris".to_string(), 30);
|
|
mapa.insert("Cyril".to_string(), 22);
|
|
|
|
// Cez páry — poradie NIE JE garantované!
|
|
for (meno, vek) in &mapa {
|
|
println!("{}: {}", meno, vek);
|
|
}
|
|
|
|
// Len kľúče
|
|
for meno in mapa.keys() {
|
|
println!("{}", meno);
|
|
}
|
|
|
|
// Len hodnoty
|
|
for vek in mapa.values() {
|
|
println!("{}", vek);
|
|
}
|
|
|
|
// Meniteľné hodnoty
|
|
for vek in mapa.values_mut() {
|
|
*vek += 1;
|
|
}
|
|
```
|
|
|
|
### Úlohy 4
|
|
|
|
**4a.** Vytvor mapu produktov (názov → cena). Vypíš všetky produkty vo formáte `"Produkt: cena €"`.
|
|
|
|
**4b.** Napíš funkciu, ktorá vráti vektor všetkých kľúčov z mapy:
|
|
```rust
|
|
fn kluce(mapa: &HashMap<String, i32>) -> Vec<&String>
|
|
```
|
|
|
|
**4c.** Napíš funkciu, ktorá zvýši všetky hodnoty v mape o 10:
|
|
```rust
|
|
fn zvys_vsetky(mapa: &mut HashMap<String, i32>)
|
|
```
|
|
|
|
**4d.** Napíš funkciu, ktorá vráti súčet všetkých hodnôt:
|
|
```rust
|
|
fn sucet_hodnot(mapa: &HashMap<String, i32>) -> i32
|
|
```
|
|
Použi `.values()` a `.sum()`.
|
|
|
|
---
|
|
|
|
## Kapitola 5: get_mut — zmena hodnoty na mieste
|
|
|
|
Ak chceš zmeniť jednu konkrétnu hodnotu (nie všetky), použi `get_mut`:
|
|
|
|
```rust
|
|
let mut mapa = HashMap::new();
|
|
mapa.insert("Anna".to_string(), 25);
|
|
|
|
// get_mut vráti Option<&mut V>
|
|
if let Some(vek) = mapa.get_mut("Anna") {
|
|
*vek += 1; // Anna má teraz 26
|
|
}
|
|
|
|
// Ak kľúč neexistuje, get_mut vráti None
|
|
if let Some(vek) = mapa.get_mut("Boris") {
|
|
*vek += 1; // Toto sa nevykoná
|
|
}
|
|
```
|
|
|
|
### Úlohy 5
|
|
|
|
**5a.** Máš mapu študentov (meno → počet bodov). Napíš funkciu, ktorá pridá body jednému študentovi:
|
|
```rust
|
|
fn pridaj_body(mapa: &mut HashMap<String, u32>, meno: &str, body: u32) -> bool
|
|
```
|
|
Vráti `true` ak študent existoval, `false` ak nie.
|
|
|
|
**5b.** Napíš funkciu, ktorá zdvojnásobí hodnotu pre daný kľúč:
|
|
```rust
|
|
fn zdvojnasob(mapa: &mut HashMap<String, i32>, kluc: &str) -> Option<i32>
|
|
```
|
|
Vráti novú hodnotu ak kľúč existoval, None ak nie.
|
|
|
|
---
|
|
|
|
## Kapitola 6: Entry API — or_insert
|
|
|
|
Toto je najdôležitejšia časť. Entry API rieši situáciu: "ak kľúč neexistuje, vlož default; ak existuje, použi existujúcu hodnotu."
|
|
|
|
```rust
|
|
let mut mapa: HashMap<String, i32> = HashMap::new();
|
|
|
|
// entry() vráti Entry — buď Vacant (prázdny) alebo Occupied (obsadený)
|
|
// or_insert(hodnota) — ak Vacant, vlož hodnotu. Vráti &mut na hodnotu.
|
|
|
|
mapa.entry("Anna".to_string()).or_insert(25);
|
|
// Anna neexistovala → vloží 25 → mapa = {"Anna": 25}
|
|
|
|
mapa.entry("Anna".to_string()).or_insert(99);
|
|
// Anna existuje → NEVLOŽÍ 99 → mapa = {"Anna": 25} (nezmenené!)
|
|
```
|
|
|
|
**Hlavné použitie — počítanie výskytov:**
|
|
|
|
```rust
|
|
let slova = vec!["ahoj", "svet", "ahoj", "rust", "svet", "ahoj"];
|
|
let mut pocty: HashMap<String, usize> = HashMap::new();
|
|
|
|
for slovo in &slova {
|
|
*pocty.entry(slovo.to_string()).or_insert(0) += 1;
|
|
}
|
|
// {"ahoj": 3, "svet": 2, "rust": 1}
|
|
```
|
|
|
|
Čo sa deje krok po kroku:
|
|
```
|
|
Slovo "ahoj":
|
|
entry("ahoj") → Vacant → or_insert(0) vloží 0 → vráti &mut 0
|
|
*(&mut 0) += 1 → hodnota je 1
|
|
|
|
Slovo "svet":
|
|
entry("svet") → Vacant → or_insert(0) vloží 0 → vráti &mut 0
|
|
*(&mut 0) += 1 → hodnota je 1
|
|
|
|
Slovo "ahoj" (druhýkrát):
|
|
entry("ahoj") → Occupied (hodnota 1) → or_insert(0) NEVLOŽÍ → vráti &mut 1
|
|
*(&mut 1) += 1 → hodnota je 2
|
|
```
|
|
|
|
### Úlohy 6
|
|
|
|
**6a.** Spočítaj výskyt každého znaku v reťazci `"abrakadabra"`. Použi `entry` + `or_insert`. Výsledok vypíš.
|
|
|
|
**6b.** Máš vektor čísel `[1, 3, 2, 1, 4, 3, 2, 1, 5]`. Spočítaj koľkokrát sa vyskytuje každé číslo.
|
|
|
|
**6c.** Čo vypíše? Tipni, potom over:
|
|
```rust
|
|
let mut m: HashMap<&str, i32> = HashMap::new();
|
|
m.entry("a").or_insert(10);
|
|
m.entry("b").or_insert(20);
|
|
m.entry("a").or_insert(99);
|
|
m.insert("b", 99);
|
|
println!("{:?}", m.get("a"));
|
|
println!("{:?}", m.get("b"));
|
|
```
|
|
|
|
---
|
|
|
|
## Kapitola 7: Entry API — or_default
|
|
|
|
`or_default()` je skratka za `or_insert(Default::default())`. Vloží defaultnú hodnotu pre daný typ.
|
|
|
|
| Typ | Default |
|
|
|-----|---------|
|
|
| usize, i32, u32... | 0 |
|
|
| f64 | 0.0 |
|
|
| bool | false |
|
|
| String | "" |
|
|
| Vec<T> | vec![] |
|
|
|
|
```rust
|
|
let mut pocty: HashMap<String, usize> = HashMap::new();
|
|
|
|
// Tieto dva riadky robia to isté:
|
|
*pocty.entry("ahoj".to_string()).or_insert(0) += 1;
|
|
*pocty.entry("ahoj".to_string()).or_default() += 1;
|
|
```
|
|
|
|
**Hlavné použitie — zoskupovanie do vektorov:**
|
|
|
|
```rust
|
|
let mut skupiny: HashMap<String, Vec<String>> = HashMap::new();
|
|
|
|
// or_default() pre Vec vloží prázdny vektor
|
|
skupiny.entry("ovocie".to_string()).or_default().push("jablko".to_string());
|
|
skupiny.entry("ovocie".to_string()).or_default().push("hruška".to_string());
|
|
skupiny.entry("zelenina".to_string()).or_default().push("mrkva".to_string());
|
|
// {"ovocie": ["jablko", "hruška"], "zelenina": ["mrkva"]}
|
|
```
|
|
|
|
### Úlohy 7
|
|
|
|
**7a.** Máš vektor slov. Zoskup ich podľa prvého písmena do HashMap<char, Vec<String>>:
|
|
```rust
|
|
let slova = vec!["auto", "ahoj", "banán", "breza", "citrón", "auto"];
|
|
// Výsledok: {'a': ["auto", "ahoj", "auto"], 'b': ["banán", "breza"], 'c': ["citrón"]}
|
|
```
|
|
|
|
**7b.** Máš vektor dvojíc (študent, predmet). Zoskup predmety podľa študenta:
|
|
```rust
|
|
let data = vec![
|
|
("Anna", "Matematika"),
|
|
("Boris", "Fyzika"),
|
|
("Anna", "Fyzika"),
|
|
("Boris", "Chémia"),
|
|
("Anna", "Chémia"),
|
|
];
|
|
// Výsledok: {"Anna": ["Matematika", "Fyzika", "Chémia"], "Boris": ["Fyzika", "Chémia"]}
|
|
```
|
|
|
|
---
|
|
|
|
## Kapitola 8: Entry API — and_modify
|
|
|
|
`and_modify` ti umožní spraviť niečo s existujúcou hodnotou pred tým, ako sa rozhodne čo robiť:
|
|
|
|
```rust
|
|
let mut mapa: HashMap<String, i32> = HashMap::new();
|
|
|
|
// Ak existuje → zvýš o 1. Ak neexistuje → vlož 1.
|
|
mapa.entry("Anna".to_string())
|
|
.and_modify(|v| *v += 1)
|
|
.or_insert(1);
|
|
// Anna neexistovala → vloží 1
|
|
|
|
mapa.entry("Anna".to_string())
|
|
.and_modify(|v| *v += 1)
|
|
.or_insert(1);
|
|
// Anna existuje s hodnotou 1 → and_modify zvýši na 2
|
|
```
|
|
|
|
Toto je užitočné keď chceš robiť rôzne veci pre nový vs existujúci kľúč.
|
|
|
|
### Úlohy 8
|
|
|
|
**8a.** Máš vektor mien. Pre každé meno: ak sa vyskytlo prvýkrát, vlož `1`. Ak sa vyskytlo znovu, zvýš o `1`. Použi `and_modify` + `or_insert`. (Áno, výsledok je rovnaký ako cez `or_insert(0) += 1`, ale precvič si syntax.)
|
|
|
|
**8b.** Máš mapu produktov (String → (cena: f64, počet: u32)). Napíš kód, ktorý: ak produkt existuje, zvýši počet o 1. Ak neexistuje, vloží ho s cenou 10.0 a počtom 1.
|
|
```rust
|
|
let mut produkty: HashMap<String, (f64, u32)> = HashMap::new();
|
|
// tvoj kód pre produkt "mlieko"
|
|
```
|
|
|
|
---
|
|
|
|
## Kapitola 9: Iterátory s HashMap
|
|
|
|
HashMap sa dá kombinovať s iterátorovými metódami:
|
|
|
|
```rust
|
|
let mut mapa = HashMap::new();
|
|
mapa.insert("Anna".to_string(), 25);
|
|
mapa.insert("Boris".to_string(), 30);
|
|
mapa.insert("Cyril".to_string(), 17);
|
|
|
|
// filter — nechaj len dospelých
|
|
let dospeli: HashMap<&String, &i32> = mapa.iter()
|
|
.filter(|(_, vek)| **vek >= 18)
|
|
.collect();
|
|
|
|
// find — nájdi prvého s daným menom
|
|
let boris: Option<(&String, &i32)> = mapa.iter()
|
|
.find(|(meno, _)| meno.as_str() == "Boris");
|
|
|
|
// max_by_key — najstarší
|
|
let najstarsi: Option<(&String, &i32)> = mapa.iter()
|
|
.max_by_key(|(_, vek)| *vek);
|
|
|
|
// Kľúče do Vec
|
|
let mena: Vec<&String> = mapa.keys().collect();
|
|
|
|
// Hodnoty — súčet
|
|
let sucet_vekov: i32 = mapa.values().sum();
|
|
```
|
|
|
|
### Úlohy 9
|
|
|
|
**9a.** Máš `HashMap<String, f64>` (produkt → cena). Nájdi najdrahší produkt. Vráť jeho názov ako `Option<&String>`.
|
|
|
|
**9b.** Máš `HashMap<String, u32>` (mesto → populácia). Vráť Vec miest s populáciou nad 100_000.
|
|
|
|
**9c.** Máš `HashMap<String, Vec<String>>` (kategória → produkty). Nájdi celkový počet produktov naprieč všetkými kategóriami. Použi `.values()` a `.map()` a `.sum()`.
|
|
|
|
---
|
|
|
|
## Kapitola 10: Praktické vzory zo skúšky
|
|
|
|
### Vzor 1: Počítanie podľa poľa štruktúry
|
|
|
|
```rust
|
|
struct Kniha { nazov: String, vydavatelstvo: String }
|
|
|
|
fn pocty_podla_vydavatelstva(knihy: &[Kniha]) -> HashMap<String, usize> {
|
|
let mut mapa = HashMap::new();
|
|
for kniha in knihy {
|
|
*mapa.entry(kniha.vydavatelstvo.clone()).or_insert(0) += 1;
|
|
}
|
|
mapa
|
|
}
|
|
```
|
|
|
|
### Vzor 2: Výpis vo formáte "Kľúč: hodnota"
|
|
|
|
```rust
|
|
fn vypis_statistiky(knihy: &[Kniha]) {
|
|
let pocty = pocty_podla_vydavatelstva(knihy);
|
|
for (vydavatelstvo, pocet) in &pocty {
|
|
println!("{}: {}", vydavatelstvo, pocet);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Vzor 3: Nájdi najčastejší
|
|
|
|
```rust
|
|
fn najcastejsie_vydavatelstvo(knihy: &[Kniha]) -> Option<String> {
|
|
let pocty = pocty_podla_vydavatelstva(knihy);
|
|
pocty.into_iter()
|
|
.max_by_key(|(_, pocet)| *pocet)
|
|
.map(|(vydavatelstvo, _)| vydavatelstvo)
|
|
}
|
|
```
|
|
|
|
### Úlohy 10
|
|
|
|
**10a.** Máš:
|
|
```rust
|
|
struct Zamestnanec { meno: String, oddelenie: String, plat: u32 }
|
|
```
|
|
Napíš funkciu `pocet_na_oddeleni(zamestnanci: &[Zamestnanec]) -> HashMap<String, usize>`.
|
|
|
|
**10b.** Napíš funkciu `celkovy_plat_na_oddeleni(zamestnanci: &[Zamestnanec]) -> HashMap<String, u32>` — súčet platov na každom oddelení.
|
|
|
|
**10c.** Napíš funkciu `vypis_statistiky(zamestnanci: &[Zamestnanec])` — pre každé oddelenie vypíše počet ľudí a celkový plat.
|
|
|
|
**10d.** Napíš funkciu `oddelenie_s_najvyssim_platom(zamestnanci: &[Zamestnanec]) -> Option<String>` — oddelenie kde je najväčší celkový plat.
|
|
|
|
---
|
|
|
|
---
|
|
|
|
---
|
|
|
|
# RIEŠENIA
|
|
|
|
## 1a
|
|
|
|
```rust
|
|
let mut ovocie: HashMap<String, f64> = HashMap::new();
|
|
ovocie.insert("Jablko".to_string(), 1.50);
|
|
ovocie.insert("Banán".to_string(), 2.00);
|
|
ovocie.insert("Pomaranč".to_string(), 2.50);
|
|
```
|
|
|
|
## 1b
|
|
|
|
```
|
|
Some(1)
|
|
```
|
|
Lebo `"x"` už existoval s hodnotou 1, `insert` ho prepísal na 99 a vrátil starú hodnotu.
|
|
|
|
## 1c
|
|
|
|
```rust
|
|
let data = vec![("sk", "Slovensko"), ("cz", "Česko"), ("pl", "Poľsko")];
|
|
let mapa: HashMap<&str, &str> = data.into_iter().collect();
|
|
```
|
|
|
|
## 2a
|
|
|
|
```rust
|
|
if let Some(cena) = ovocie.get("Jablko") {
|
|
println!("Cena: {} €", cena);
|
|
} else {
|
|
println!("Nemáme");
|
|
}
|
|
```
|
|
|
|
## 2b
|
|
|
|
```rust
|
|
fn je_v_mape(mapa: &HashMap<String, i32>, kluc: &str) -> bool {
|
|
mapa.contains_key(kluc)
|
|
}
|
|
```
|
|
|
|
## 2c
|
|
|
|
```
|
|
Some(1)
|
|
None
|
|
1
|
|
true
|
|
false
|
|
```
|
|
|
|
## 3a
|
|
|
|
```rust
|
|
let mut mapa = HashMap::new();
|
|
mapa.insert("A".to_string(), 1);
|
|
mapa.insert("B".to_string(), 2);
|
|
mapa.insert("C".to_string(), 3);
|
|
|
|
let odstraneny = mapa.remove("B");
|
|
println!("{:?}", odstraneny); // Some(2)
|
|
println!("{}", mapa.len()); // 2
|
|
```
|
|
|
|
## 3b
|
|
|
|
```rust
|
|
fn odstran_ak_existuje(mapa: &mut HashMap<String, i32>, kluc: &str) -> Option<i32> {
|
|
mapa.remove(kluc)
|
|
}
|
|
```
|
|
|
|
## 4a
|
|
|
|
```rust
|
|
let mut produkty = HashMap::new();
|
|
produkty.insert("Chlieb".to_string(), 1.20);
|
|
produkty.insert("Mlieko".to_string(), 0.89);
|
|
produkty.insert("Maslo".to_string(), 2.50);
|
|
|
|
for (nazov, cena) in &produkty {
|
|
println!("{}: {} €", nazov, cena);
|
|
}
|
|
```
|
|
|
|
## 4b
|
|
|
|
```rust
|
|
fn kluce(mapa: &HashMap<String, i32>) -> Vec<&String> {
|
|
mapa.keys().collect()
|
|
}
|
|
```
|
|
|
|
## 4c
|
|
|
|
```rust
|
|
fn zvys_vsetky(mapa: &mut HashMap<String, i32>) {
|
|
for hodnota in mapa.values_mut() {
|
|
*hodnota += 10;
|
|
}
|
|
}
|
|
```
|
|
|
|
## 4d
|
|
|
|
```rust
|
|
fn sucet_hodnot(mapa: &HashMap<String, i32>) -> i32 {
|
|
mapa.values().sum()
|
|
}
|
|
```
|
|
|
|
## 5a
|
|
|
|
```rust
|
|
fn pridaj_body(mapa: &mut HashMap<String, u32>, meno: &str, body: u32) -> bool {
|
|
if let Some(aktualne) = mapa.get_mut(meno) {
|
|
*aktualne += body;
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
```
|
|
|
|
## 5b
|
|
|
|
```rust
|
|
fn zdvojnasob(mapa: &mut HashMap<String, i32>, kluc: &str) -> Option<i32> {
|
|
let hodnota = mapa.get_mut(kluc)?;
|
|
*hodnota *= 2;
|
|
Some(*hodnota)
|
|
}
|
|
```
|
|
|
|
## 6a
|
|
|
|
```rust
|
|
let text = "abrakadabra";
|
|
let mut pocty: HashMap<char, usize> = HashMap::new();
|
|
for c in text.chars() {
|
|
*pocty.entry(c).or_insert(0) += 1;
|
|
}
|
|
for (znak, pocet) in &pocty {
|
|
println!("{}: {}", znak, pocet);
|
|
}
|
|
```
|
|
|
|
## 6b
|
|
|
|
```rust
|
|
let cisla = vec![1, 3, 2, 1, 4, 3, 2, 1, 5];
|
|
let mut pocty: HashMap<i32, usize> = HashMap::new();
|
|
for c in &cisla {
|
|
*pocty.entry(*c).or_insert(0) += 1;
|
|
}
|
|
// {1: 3, 3: 2, 2: 2, 4: 1, 5: 1}
|
|
```
|
|
|
|
## 6c
|
|
|
|
```
|
|
Some(10)
|
|
Some(99)
|
|
```
|
|
`entry("a").or_insert(99)` — "a" už existuje, takže 99 sa NEVLOŽÍ, ostáva 10.
|
|
`insert("b", 99)` — insert VŽDY prepíše, takže "b" je teraz 99.
|
|
|
|
## 7a
|
|
|
|
```rust
|
|
let slova = vec!["auto", "ahoj", "banán", "breza", "citrón", "auto"];
|
|
let mut skupiny: HashMap<char, Vec<String>> = HashMap::new();
|
|
for slovo in &slova {
|
|
if let Some(prvy) = slovo.chars().next() {
|
|
skupiny.entry(prvy).or_default().push(slovo.to_string());
|
|
}
|
|
}
|
|
```
|
|
|
|
## 7b
|
|
|
|
```rust
|
|
let data = vec![
|
|
("Anna", "Matematika"),
|
|
("Boris", "Fyzika"),
|
|
("Anna", "Fyzika"),
|
|
("Boris", "Chémia"),
|
|
("Anna", "Chémia"),
|
|
];
|
|
let mut mapa: HashMap<String, Vec<String>> = HashMap::new();
|
|
for (student, predmet) in &data {
|
|
mapa.entry(student.to_string()).or_default().push(predmet.to_string());
|
|
}
|
|
```
|
|
|
|
## 8a
|
|
|
|
```rust
|
|
let mena = vec!["Anna", "Boris", "Anna", "Cyril", "Boris", "Anna"];
|
|
let mut pocty: HashMap<String, i32> = HashMap::new();
|
|
for meno in &mena {
|
|
pocty.entry(meno.to_string())
|
|
.and_modify(|v| *v += 1)
|
|
.or_insert(1);
|
|
}
|
|
// {"Anna": 3, "Boris": 2, "Cyril": 1}
|
|
```
|
|
|
|
## 8b
|
|
|
|
```rust
|
|
let mut produkty: HashMap<String, (f64, u32)> = HashMap::new();
|
|
produkty.entry("mlieko".to_string())
|
|
.and_modify(|(_, pocet)| *pocet += 1)
|
|
.or_insert((10.0, 1));
|
|
```
|
|
|
|
## 9a
|
|
|
|
```rust
|
|
fn najdrahsi(mapa: &HashMap<String, f64>) -> Option<&String> {
|
|
mapa.iter()
|
|
.max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap())
|
|
.map(|(nazov, _)| nazov)
|
|
}
|
|
```
|
|
|
|
## 9b
|
|
|
|
```rust
|
|
fn velke_mesta(mapa: &HashMap<String, u32>) -> Vec<&String> {
|
|
mapa.iter()
|
|
.filter(|(_, pop)| **pop > 100_000)
|
|
.map(|(mesto, _)| mesto)
|
|
.collect()
|
|
}
|
|
```
|
|
|
|
## 9c
|
|
|
|
```rust
|
|
fn celkovy_pocet(mapa: &HashMap<String, Vec<String>>) -> usize {
|
|
mapa.values().map(|v| v.len()).sum()
|
|
}
|
|
```
|
|
|
|
## 10a
|
|
|
|
```rust
|
|
fn pocet_na_oddeleni(zamestnanci: &[Zamestnanec]) -> HashMap<String, usize> {
|
|
let mut mapa = HashMap::new();
|
|
for z in zamestnanci {
|
|
*mapa.entry(z.oddelenie.clone()).or_insert(0) += 1;
|
|
}
|
|
mapa
|
|
}
|
|
```
|
|
|
|
## 10b
|
|
|
|
```rust
|
|
fn celkovy_plat_na_oddeleni(zamestnanci: &[Zamestnanec]) -> HashMap<String, u32> {
|
|
let mut mapa: HashMap<String, u32> = HashMap::new();
|
|
for z in zamestnanci {
|
|
*mapa.entry(z.oddelenie.clone()).or_insert(0) += z.plat;
|
|
}
|
|
mapa
|
|
}
|
|
```
|
|
|
|
## 10c
|
|
|
|
```rust
|
|
fn vypis_statistiky(zamestnanci: &[Zamestnanec]) {
|
|
let pocty = pocet_na_oddeleni(zamestnanci);
|
|
let platy = celkovy_plat_na_oddeleni(zamestnanci);
|
|
for (oddelenie, pocet) in &pocty {
|
|
let plat = platy.get(oddelenie).unwrap_or(&0);
|
|
println!("{}: {} ľudí, celkový plat: {}", oddelenie, pocet, plat);
|
|
}
|
|
}
|
|
```
|
|
|
|
## 10d
|
|
|
|
```rust
|
|
fn oddelenie_s_najvyssim_platom(zamestnanci: &[Zamestnanec]) -> Option<String> {
|
|
let platy = celkovy_plat_na_oddeleni(zamestnanci);
|
|
platy.into_iter()
|
|
.max_by_key(|(_, plat)| *plat)
|
|
.map(|(oddelenie, _)| oddelenie)
|
|
}
|
|
```
|