TL;DR
RustでHashMap
の中身のVec
を変更するにはget_mut()
を使う.
本題
例えば,以下のようなHashMap
を作成したとする.
HashMapの作成
use std::collections::HashMap;
fn main(){
let mut map: HashMap<char, Vec<usize>> = HashMap::new();
map.insert('a', vec![1,2,3]);
map.insert('b', vec![4,5,6]);
}
つまり,map = {'a': [1,2,3], 'b': [4,5,6]}
のようにHashMap
の中身がVec
のものだ.
本稿では,中身のVec
の任意の要素を削除する方法を解説する.
インデックスを求める
map['a']
の要素1
を消したいとき,まず1
がmap['a']
の何番目にあるか求める必要がある.
ここで,map['a']
に1
が含まれることが既知であるとする.
Indexを求める
// まずはIndexを取得する
let index = map[&'a'].iter().position(|x| *x == 1).unwrap();
試しに以下のコードをコンパイルして実行してみる.
テストコード
use std::collections::HashMap;
fn main(){
let mut map: HashMap<char, Vec<usize>> = HashMap::new();
map.insert('a', vec![1,2,3]);
map.insert('b', vec![4,5,6]);
println!("{:?}", map);
// まずはIndexを取得する
let index = map[&'a'].iter().position(|x| *x == 1).unwrap();
println!("{}", index);
}
実行結果
{'a': [1, 2, 3], 'b': [4, 5, 6]}
0
直感的な実装
Vec
からインデックスを指定して要素を削除するメソッドとして,本稿ではremove()
を使用する.
このとき,筆者のような初学者であれば,以下のようなコードを書くと思う.
// Indexを指定して要素を削除
map[&'a'].remove(index);
これはコンパイラに叱られる.
error[E0596]: cannot borrow data in a `&` reference as mutable
--> src/main.rs:13:3
|
13 | map[&'a'].remove(index);
| ^^^^^^^^^ cannot borrow as mutable
|
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<char, std::vec::Vec<usize>>`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`.
メッセージを読むと,HashMap
にはVec
のようにIndexMut
が実装されていないことがわかる1.
実際に動く方法
TL;DRで記したとおり,get_mut()
を使う.
// Indexを指定して要素を削除
map.get_mut(&'a').unwrap().remove(index);
実行してみる.
テストコード
use std::collections::HashMap;
fn main(){
let mut map: HashMap<char, Vec<usize>> = HashMap::new();
map.insert('a', vec![1,2,3]);
map.insert('b', vec![4,5,6]);
println!("{:?}", map);
// まずはIndexを取得する
let index = map[&'a'].iter().position(|x| *x == 1).unwrap();
println!("{}", index);
// Indexを指定して削除
map.get_mut(&'a').unwrap().remove(index);
println!("{:?}", map);
}
実行結果
{'a': [1, 2, 3], 'b': [4, 5, 6]}
0
{'a': [2, 3], 'b': [4, 5, 6]}