6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RustでHashMapの中身のVecを変更する

Last updated at Posted at 2019-12-02

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を消したいとき,まず1map['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]}
  1. もともとは実装されていたが削除されたらしい 参考1 参考2

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?