HashMap di Rust
HashMap menyimpan data sebagai pasangan key-value (kunci-nilai). Kamu mencari data berdasarkan key, bukan berdasarkan posisi seperti pada array atau vektor. Kalau kamu pernah memakai dictionary di Python atau object sebagai map di JavaScript, idenya sama persis.
Membuat HashMap
Section titled “Membuat HashMap”use std::collections::HashMap;
fn main() { let mut ages = HashMap::new();
ages.insert("Alice", 30); ages.insert("Bob", 25);
println!("{:?}", ages);}Baris use std::collections::HashMap; di bagian atas membawa tipe ini ke dalam cakupan (scope). Berbeda dengan Vec dan String, HashMap tidak tersedia secara otomatis, jadi baris ini wajib ada.
Mencari sebuah nilai
Section titled “Mencari sebuah nilai”use std::collections::HashMap;
fn main() { let mut ages = HashMap::new(); ages.insert("Alice", 30);
match ages.get("Alice") { Some(age) => println!("Umur Alice {age} tahun"), None => println!("Tidak ditemukan"), }}.get() mengembalikan Option, bukan nilainya langsung, karena bisa saja key-nya tidak ada. Kita akan membahas Option dengan lengkap di halamannya sendiri. Untuk sekarang, match dengan Some/None adalah cara standar untuk menanganinya.
Memperbarui sebuah nilai
Section titled “Memperbarui sebuah nilai”Melakukan insert lagi dengan key yang sama akan menimpa nilai yang lama:
use std::collections::HashMap;
fn main() { let mut ages = HashMap::new(); ages.insert("Alice", 30); ages.insert("Alice", 31); // menimpa 30
println!("{:?}", ages.get("Alice"));}Kalau kamu hanya ingin memasukkan nilai ketika key-nya belum ada, pakai .entry():
use std::collections::HashMap;
fn main() { let mut ages = HashMap::new(); ages.insert("Alice", 30);
ages.entry("Alice").or_insert(99); // Alice sudah ada, jadi ini tidak melakukan apa-apa ages.entry("Bob").or_insert(25); // Bob belum ada, jadi ini memasukkannya
println!("{:?}", ages);}Perulangan pada HashMap
Section titled “Perulangan pada HashMap”use std::collections::HashMap;
fn main() { let mut ages = HashMap::new(); ages.insert("Alice", 30); ages.insert("Bob", 25);
for (name, age) in &ages { println!("Umur {name} {age} tahun"); }}Kapan memakai HashMap
Section titled “Kapan memakai HashMap”Pakai HashMap setiap kali kamu ingin mencari sesuatu berdasarkan nama atau ID, bukan berdasarkan posisi: menghitung frekuensi kata, memetakan username ke data pengguna, atau menyimpan cache hasil berdasarkan key. Kalau urutan penting atau kamu hanya mengolah daftar biasa, Vec lebih cocok.
Latihan
Section titled “Latihan”1. Buku telepon mini
Section titled “1. Buku telepon mini”Simpan tiga nama beserta nomor teleponnya di sebuah HashMap. Lalu cari "Ben" (yang ada di dalamnya) dan "Dana" (yang tidak ada), dan cetak satu baris yang ramah untuk masing-masing. Petunjuk: lakukan perulangan pada ["Ben", "Dana"] dan pakai match pada .get(name).
Lihat solusi
use std::collections::HashMap;
fn main() { let mut phone_book = HashMap::new(); phone_book.insert("Ana", "555-1234"); phone_book.insert("Ben", "555-9876"); phone_book.insert("Chen", "555-4321");
for name in ["Ben", "Dana"] { match phone_book.get(name) { Some(number) => println!("{name}: {number}"), None => println!("{name}: tidak ada di buku telepon"), } }}Output:
Ben: 555-9876Dana: tidak ada di buku teleponMelakukan perulangan pada nama-nama yang kita cari, bukan pada map-nya, juga memberi kita urutan yang tetap. Trik ini berguna setiap kali kamu butuh output yang bisa ditebak dari sebuah HashMap.
2. Hitung suara
Section titled “2. Hitung suara”Kamu punya suara ["merah", "biru", "merah", "hijau", "biru", "merah"]. Hitung berapa suara yang didapat setiap warna, lalu cetak totalnya untuk "merah", "hijau", "biru", dan "pink" (yang tidak dapat suara sama sekali). Petunjuk: counts.entry(color).or_insert(0) memberimu jumlah saat ini untuk warna itu, dimulai dari 0. Tambahkan satu dengan *count += 1.
Lihat solusi
use std::collections::HashMap;
fn main() { let votes = ["merah", "biru", "merah", "hijau", "biru", "merah"]; let mut counts = HashMap::new();
for color in votes { let count = counts.entry(color).or_insert(0); *count += 1; }
for color in ["merah", "hijau", "biru", "pink"] { match counts.get(color) { Some(n) => println!("{color}: {n}"), None => println!("{color}: 0"), } }}Output:
merah: 3hijau: 1biru: 2pink: 0or_insert(0) mengembalikan referensi mutable ke nilai yang tersimpan di map, bukan salinannya. Tanda * pada *count += 1 artinya “ubah angka yang ditunjuk oleh ini”, sehingga map-nya sendiri ikut diperbarui. Pola “entry, atau insert 0, lalu tambah 1” ini adalah cara standar untuk menghitung sesuatu di Rust.
Ringkasan
Section titled “Ringkasan”HashMap<K, V>menyimpan pasangan key-value; bawa ke dalam cakupan denganuse std::collections::HashMap;..insert(key, value)menambah atau menimpa;.get(key)mencari dan mengembalikanOption..entry(key).or_insert(value)hanya memasukkan nilai kalau key-nya belum ada.- Urutan saat perulangan tidak dijamin, jadi jangan bergantung padanya.
Kuis singkat
Section titled “Kuis singkat”Kuis singkat
1. Apa yang kamu perlukan untuk membawa HashMap ke dalam cakupan, tidak seperti Vec atau String?
2. Apa yang dilakukan .entry(key).or_insert(value)?
3. Bisakah kamu mengandalkan urutan entri yang tercetak saat perulangan pada HashMap?
Skor: 0 / 3
Bacaan lebih lanjut
Section titled “Bacaan lebih lanjut”- Storing Keys with Associated Values in Hash Maps — The Rust Book (bahasa Inggris): membahas ownership dari key dan value, plus contoh penghitung kata yang memperbarui nilai.
- HashMap — Rust by Example (bahasa Inggris): contoh daftar kontak yang bisa dijalankan, memakai
insert,get,remove, dan perulangan. HashMap— dokumentasi standard library (bahasa Inggris): semua method-nya, termasukcontains_key,remove,keys, danvalues.Entry— dokumentasi standard library (bahasa Inggris): semua yang bisa kamu lakukan dengan.entry(), sepertior_insert_withdanand_modify.