[TS] Mapオブジェクトの使い方

## 概要
TypeScriptを利用する際に、Objcetはよく利用するのですが  
Mapオブジェクトについては扱うことがほぼなかったため  
基礎的な利用法をまとめてみました。

## Mapオブジェクトとは
Mapオブジェクトは、key・valueのペアを取り扱うためのオブジェクトであり  
保存したデータの管理も柔軟に行うことが可能である。  
また、オブジェクトと非常に似通っているが別物となる。  
  
下記のサンプルコードは、Mapオブジェクトの作成から  
値の格納と取り出しまでの流れを記述したものになる。
```ts
// 新規のMapオブジェクト作成
const mapObj = new Map<string, number>();

// 作成したMapオブジェクトに対して、key・valueで値を入れる
mapObj.set("one", 1);

// 入れた値の取り出し
console.log(mapObj.get("one")); 
// 1
```

## MapオブジェクトにおけるCRUD
### Create (生成)
要素の生成は新規でMapオブジェクトを作成し、  
その中にset()メソッドで値を入れていくこともできるが  
配列に変換したオブジェクトを利用して、作成時に値を入れてしまうことも可能である。
```ts
const obj = { a: 1, b: 2, c: 3 };

// Objectを配列に変換してから渡す
const mapObj = new Map<string, number>(Object.entries(obj));
mapObj.set('d', 4);

console.log(Object.entries(obj))
console.log(mapObj);
// [['a', 1], ['b', 2], ['c', 3]]
// Map(4) { 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4 }
```

### Read (読み取り)
要素の取得は、get()メソッドで行うことができる。  
オブジェクトのようにドット記法・ブラケット記法での読み取りは不可。
```ts
const obj = { a: 1, b: 2, c: 3 };

const mapObj = new Map<string, number>(Object.entries(obj));

console.log(mapObj.get("a"))
// 1

// 以下での値の読み取りは不可
console.log(mapObj.a)
console.log(mapObj["a"])
```

### Update (更新)
要素の更新においても、データ作成で利用したset()メソッドを利用する。
keyとvalueを指定し、既存の値の更新を行う。
```ts
const obj = { a: 1, b: 2, c: 3 };

const mapObj = new Map<string, number>(Object.entries(obj));

// 任意のkeyを指定し、値の更新を行う
mapObj.set("a", 2)
mapObj.set("b", 4)
mapObj.set("c", 6)

console.log(mapObj)
// Map(3) { 'a' => 2, 'b' => 4, 'c' => 6 }
```

### Delete (削除)
#### 指定要素の削除
要素の削除において、指定の値を削除するにはdelete()メソッドを利用する。
```ts
const obj = { a: 1, b: 2, c: 3 };

const mapObj = new Map<string, number>(Object.entries(obj));

// keyを指定し、削除を行う
mapObj.delete("c")

console.log(mapObj)
// Map(2) { 'a' => 1, 'b' => 2 }
```

#### 保有データの全削除
要素の全削除を行う場合は、clear()メソッドを利用する。  
Mapオブジェクトに格納されたデータが全て削除されるので注意が必要である。
```ts
const obj = { a: 1, b: 2, c: 3 };

const mapObj = new Map<string, number>(Object.entries(obj));

// 保有するデータ全ての削除を行う
mapObj.clear()

console.log(mapObj)
// Map(0) {}
```

## valueに対してオブジェクトの格納
値としてオブジェクトを格納することも可能であり  
その際は型定義が必要となってくるが、複雑なデータ構造を扱う際に便利である。
```ts
interface Spec {
    cpu : string;
    ram : number;
    rom : number;
}

const obj = { 
    product1 : { cpu : "m1", ram : 16, rom : 256 }, 
    product2 : { cpu : "m2", ram : 24, rom : 512 }, 
    product3 : { cpu : "m3", ram : 32, rom : 1000 } 
};
    
const mapObj = new Map<string, Spec>(Object.entries(obj));

console.log(Object.entries(obj))
// [
//   [ 'product1', { cpu: 'm1', ram: 16, rom: 256 } ],
//   [ 'product2', { cpu: 'm2', ram: 16, rom: 256 } ],
//   [ 'product3', { cpu: 'm3', ram: 16, rom: 256 } ]
// ]

console.log(mapObj);
// Map(3) {
//   'product1' => { cpu: 'm1', ram: 16, rom: 256 },
//   'product2' => { cpu: 'm2', ram: 16, rom: 256 },
//   'product3' => { cpu: 'm3', ram: 16, rom: 256 }
// }

console.log(mapObj.get("product1"))
// { cpu: 'm1', ram: 16, rom: 256 }

console.log(mapObj.get("product1").cpu)
// m1
```

## 参考
- Map<K, V>
  - https://typescriptbook.jp/reference/builtin-api/map
- TypeScriptで積極的にMapを使おう。
  - https://zenn.dev/nana/articles/4f170f730f2358
- 【JavaScript】これからはオブジェクトよりも Map オブジェクトを使おう！
  - https://zenn.dev/torakm/articles/48f60764434537
- Object.entries() を使ってObject → 配列変換
  - https://qiita.com/bbbks9/items/6ce80ae1c0fd28a3a9d7
- TypeScript でMapからObject、ObjectからMapへの変換
  - https://qiita.com/optimisuke/items/345490109b4f3e7dba5c