HashMap::contains_key() / remove() / entry()
| 対応: | Rust 1.0(2015) |
|---|
RustのHashMapには、キーの存在を確認する『contains_key()』、エントリを削除する『remove()』、そして値がなければ追加する『entry().or_insert()』が用意されています。
構文
use std::collections::HashMap;
// キーが存在するか確認します(bool を返します)。
let exists = map.contains_key("黒閃");
// キーとその値を削除します(Option<V> を返します)。
let removed = map.remove("黒閃"); // Some(値) または None
// entry API: キーが存在しなければ挿入します。
map.entry("key".to_string()).or_insert(0);
// entry API: 存在する値を更新します。
let count = map.entry("key".to_string()).or_insert(0);
*count += 1; // 値をインクリメントします。
メソッド一覧
| メソッド | 概要 |
|---|---|
| map.contains_key(&key) | キーが存在すればtrueを返します。 |
| map.contains_value(&value) | 値が存在すればtrueを返します(※HashMapには存在しないため手動チェックが必要)。 |
| map.remove(&key) | キーを削除し、存在した場合は値をSomeで返します。 |
| map.remove_entry(&key) | キーと値のペアをタプルとして返しながら削除します。 |
| map.entry(key) | キーのエントリを返します(OccupiedEntry または VacantEntry)。 |
| .or_insert(value) | エントリが存在しなければ値を挿入し、参照を返します。 |
| .or_insert_with(|| ...) | エントリが存在しなければクロージャの戻り値を挿入します。 |
| .or_default() | エントリが存在しなければデフォルト値(Default::default())を挿入します。 |
| .and_modify(|v| ...) | エントリが存在する場合のみ値を変更します。 |
| map.retain(|k, v| ...) | 条件を満たすエントリのみを残します。 |
サンプルコード
sample_hashmap_contains_key_remove.rs
use std::collections::HashMap;
fn main() {
let mut map: HashMap<String, i32> = HashMap::new();
map.insert("黒閃".to_string(), 3);
map.insert("領域展開".to_string(), 5);
map.insert("術式反転".to_string(), 2);
// contains_key() でキーの存在を確認します。
println!("黒閃 あり?: {}", map.contains_key("黒閃")); // true
println!("呪力操作 あり?: {}", map.contains_key("呪力操作")); // false
// remove() でエントリを削除します。
let removed = map.remove("領域展開");
println!("削除した値: {:?}", removed); // Some(5)
println!("削除後の長さ: {}", map.len()); // 2
let none = map.remove("呪力操作"); // 存在しないキー
println!("存在しないキーを削除: {:?}", none); // None
// --- entry API ---
// 呪術師の術式使用回数をカウントします(典型的なentry活用例)。
let cursed_techniques = "領域展開 術式反転 領域展開 黒閃 術式反転 黒閃 黒閃";
let mut counts: HashMap<String, i32> = HashMap::new();
for technique in cursed_techniques.split_whitespace() {
let count = counts.entry(technique.to_string()).or_insert(0);
*count += 1; // 参照を通じて値をインクリメントします。
}
println!("術式カウント: {:?}", counts);
// or_default() で Default trait のデフォルト値を使います。
let mut vmap: HashMap<String, Vec<i32>> = HashMap::new();
vmap.entry("evens".to_string()).or_default().push(2);
vmap.entry("evens".to_string()).or_default().push(4);
vmap.entry("odds".to_string()).or_default().push(1);
println!("グループ: {:?}", vmap);
// and_modify() で既存の値だけを変更します。
let mut scores: HashMap<String, i32> = HashMap::new();
scores.insert("五条悟".to_string(), 90);
scores.entry("五条悟".to_string()).and_modify(|s| *s += 10);
scores.entry("両面宿儺".to_string()).and_modify(|s| *s += 10).or_insert(0);
println!("scores: {:?}", scores); // 五条悟は100、両面宿儺は0
// retain() で条件を満たすエントリのみ残します。
let mut m: HashMap<&str, i32> = [("a", 1), ("b", 2), ("c", 3), ("d", 4)]
.iter().cloned().collect();
m.retain(|_, v| *v >= 3); // 値が3以上のエントリだけ残します。
println!("retain(value >= 3): {:?}", m);
}
rustc hashmap_contains_key_remove.rs
./hashmap_contains_key_remove
黒閃 あり?: true
呪力操作 あり?: false
削除した値: Some(5)
削除後の長さ: 2
存在しないキーを削除: None
術式カウント: {"領域展開": 2, "術式反転": 2, "黒閃": 3}
グループ: {"evens": [2, 4], "odds": [1]}
scores: {"五条悟": 100, "両面宿儺": 0}
retain(value >= 3): {"c": 3, "d": 4}
概要
entry APIはHashMapの最も慣用的な使い方の一つです。「キーが存在しなければ挿入し、存在すれば更新する」という処理を安全かつ効率的に書けます。単語カウントのような集計処理でよく使われます。
『or_insert()』は値の可変参照(&mut V)を返します。この参照を通じて値を変更できるため、インクリメントや配列への追加が可能です。
HashMapの生成・基本操作は『HashMap::new() / insert() / get()』を、イテレーションは『HashMap::keys() / values() / iter()』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。