Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Rust辞典

  1. トップページ
  2. Rust辞典
  3. HashMap::contains_key() / remove() / entry()

HashMap::contains_key() / remove() / entry()

RustのHashMapには、キーの存在を確認する『contains_key()』、エントリを削除する『remove()』、そして値がなければ追加する『entry().or_insert()』が用意されています。

構文
use std::collections::HashMap;

// キーが存在するか確認します(bool を返します)。
let exists = map.contains_key("apple");

// キーとその値を削除します(Option<V> を返します)。
let removed = map.remove("apple");  // 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| ...)条件を満たすエントリのみを残します。
サンプルコード
use std::collections::HashMap;

fn main() {
    let mut map: HashMap<String, i32> = HashMap::new();
    map.insert("apple".to_string(), 3);
    map.insert("banana".to_string(), 5);
    map.insert("cherry".to_string(), 2);

    // contains_key() でキーの存在を確認します。
    println!("apple あり?: {}", map.contains_key("apple"));   // true
    println!("grape あり?: {}", map.contains_key("grape"));   // false

    // remove() でエントリを削除します。
    let removed = map.remove("banana");
    println!("削除した値: {:?}", removed);  // Some(5)
    println!("削除後の長さ: {}", map.len());  // 2

    let none = map.remove("grape");  // 存在しないキー
    println!("存在しないキーを削除: {:?}", none);  // None

    // --- entry API ---
    // 単語の出現回数をカウントします(典型的なentry活用例)。
    let text = "hello world hello rust hello world";
    let mut counts: HashMap<String, i32> = HashMap::new();

    for word in text.split_whitespace() {
        let count = counts.entry(word.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("Alice".to_string(), 90);
    scores.entry("Alice".to_string()).and_modify(|s| *s += 10);
    scores.entry("Bob".to_string()).and_modify(|s| *s += 10).or_insert(0);
    println!("scores: {:?}", scores);  // Aliceは100、Bobは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);
}
概要

entry APIはHashMapの最も慣用的な使い方の一つです。「キーが存在しなければ挿入し、存在すれば更新する」という処理を安全かつ効率的に書けます。単語カウントのような集計処理でよく使われます。

『or_insert()』は値の可変参照(&mut V)を返します。この参照を通じて値を変更できるため、インクリメントや配列への追加が可能です。

HashMapの生成・基本操作は『HashMap::new() / insert() / get()』を、イテレーションは『HashMap::keys() / values() / iter()』を参照してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。