0
0

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 1 year has passed since last update.

Map の型

Map

Mapはキーとそれに対応する値を保持する機能を持つ組み込みオブジェクトです。
キーとして任意の値を用いることができ、オブジェクトをキーとすることも可能です。

また、Mapの型はMap<K, V>のように表されます(Kはキーの型、Vは値の型です)。

Map の操作

Mapにキーと値を追加するにはsetメソッドを利用します。

Mapに格納された値を取得するgetメソッドや、引数として渡したキーがMapに保持されているかを判定できるhasメソッドなどもあります。

type KeyObj = { key: string }
const map: Map<string | KeyObj, number> = new Map()

const keyObj: KeyObj = { key: 'value' }

map.set(keyObj, 210)

console.log(map)
// Map (1) {{ "key": "value" } => 210} 

console.log(map.has(keyObj))
// true

console.log(map.has({ key: 'value' }))
// false

{ key: 'value' }というオブジェクトをキーとしてMap に渡すことができています。

取り出すときには、setで登録したオブジェクトと同じ参照をもつオブジェクトを渡す必要があります。
同じ構造のオブジェクトを渡しただけでは、別のキーとしてみなされてしまうわけですね。

Mapの値を列挙する

Mapにはkeysvaluesentriesといった、保持している値を列挙するためのメソッドも備わっています。
これらのメソッドの返り値はイテレータと呼ばれるもので、ループ処理での使用頻度が高いです。

const map: Map<string|KeyObj,number> = new Map()
type KeyObj = {key: string}
const keyObj: KeyObj = {key: 'value'}
map.set('key1',1234)
map.set(keyObj,210)

for(const key of map.keys()){
console.log(key)
}
//"key1" 
//{"key": "value"} 

for(const value of map.values()){
console.log(value)
}
//1234
//210

for(const[key, value] of map.entries()){
    console.log(key)
    console.log(value)
}
//"key1" 
//1234 
//{"key": "value"} 
//210 

WeakMap

Mapに似た組み込みオブジェクトにWeakMapというものがあります。
Mapと違って列挙を行うためのメソッド(keysvaluesentries)を持たず、キーとしてはオブジェクト(もしくはnon-registered なシンボル)のみを設定することができ、数値や文字列を設定することはできません。

const weakMap = new WeakMap()
//Argument of type 'string' is not assignable to parameter of type 'object'.ts(2345)
weakMap.set('str','test')
//実行時エラーが発生(Invalid value used as weak map key)

ガベージコレクション

ガベージコレクションとは、使用しなくなったメモリを自動で解放する仕組みのことです。
WeakMapはこのガベージコレクションを目的として採用されることがあります。

WeakMapMapと異なる点として、キーへの参照が弱参照である点があります。

このことは、キーとして設定できる値がオブジェクトかnon-registered なシンボルしか許されていない理由の一端となっています。
registered なシンボルはガベージコレクションの対象とならないため、WeakMapのキーとしての使用が許可されていないようです。

Because registered symbols can be arbitrarily created anywhere, they behave almost exactly like the strings they wrap. Therefore, they are not guaranteed to be unique and are not garbage collectable. Therefore, registered symbols are disallowed in WeakMap, WeakSet, WeakRef, and FinalizationRegistry objects.

Mapでキーとして使用されているオブジェクトは、Map自体がガベージコレクトされない限りはガベージコレクションの対象とならず、メモリ上に保持され続けます。
これは、Mapがキーを列挙するメソッドを持っているため、キーとして登録されたオブジェクトが不要になったと判断できないためです。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?