🗺️

TypeScriptで積極的にMapを使おう。

2022/07/26に公開

TypeScriptにはMapオブジェクトというのが存在します。

Mapとは

KeyとValueを扱うオブジェクトになります。
JavaScriptの世界では、オブジェクトというと下のようなものになります。

{
  name: "nanana",
  skills: ["TypeScript", "React", "GraphQL"],
  age: 10
}

name, skills, ageがkeyとなり、対応している右側がvalueとなります。
呼び出し方は

const me = {
  name: "nanana",
  skills: ["TypeScript", "React", "GraphQL"],
  age: 10
}

me.name // "nanana"
me.skills // ["TypeScript", "React", "GraphQL"]
me.age // 10

となります。
このkey, valueをラップして、良い感じに扱えるようにした(おまけに型もつけられる)APIがMapになります。

Mapを使ってみる

まずは簡単なMapを使ってみます。

const map = new Map<string, string>();
map.set('name', 'nanana');
console.log(map.get('name')); // nanana

となります。

const map = new Map<string, string>();

ここでstring(左)をkeyとした、string(右)をvalueとしたMapオブジェクトを作り

map.set('name', 'nanana');

ここでMapオブジェクトに"name"というkeyで"nanana"というvalueをセットしています。
どちらもstringなので、型も合っています。

console.log(map.get('name')); // nanana

ここでMapオブジェクトにあるget関数を使い、keyがnameとなる、valueを出力しています。

すごくシンプルなMapになりましたね。
しかし、実際実務ではあんまりstringをキーとして、stringをvalueとするような単純なものはあまりないかと思います。
valueにオブジェクトをセットしたいと思うこともあるでしょう。
やることは基本的に同じですが、紹介しようと思います。

オブジェクトをMapに適用する

まずコードを書きます。

type Browser = {
    mantainedBy: string
    url: string
    version: number
}

const browsersMap = new Map<string, Browser>();

const companies = ['Google', 'Mozilla', 'Microsoft'];
const browsers: { name: string; url: string; version: number }[] = [
    { name: 'Chrome', url: 'https://chromeenterprise.google', version: 100 },
    { name: 'Firefox', url: 'https://www.mozilla.org/ja/firefox/new/', version: 110 },
    { name: 'Edge', url: 'https://www.microsoft.com/ja-jp/edge', version: 1.10 },
]

companies.map((com, i) => {
    browsersMap.set(com, {
        mantainedBy: browsers[i].name,
        url: browsers[i].url,
        version: browsers[i].version
    });
})

console.log(browsersMap.get('Google'))

1個ずつ解説します。

type Browser = {
    mantainedBy: string
    url: string
    version: number
}

ここでまずはブラウザに必要な情報の型を作ります。

const browsersMap = new Map<string, Browser>();

stringをkeyとして、先ほどのブラウザの型をvalueとして格納できるMapオブジェクトを作成します。

const companies = ['Google', 'Mozilla', 'Microsoft'];
const browsers: { name: string; url: string; version: number }[] = [
    { name: 'Chrome', url: 'https://chromeenterprise.google', version: 100 },
    { name: 'Firefox', url: 'https://www.mozilla.org/ja/firefox/new/', version: 110 },
    { name: 'Edge', url: 'https://www.microsoft.com/ja-jp/edge', version: 1.10 },
]

データです。
大体APIなど外部から取得したデータになるかと思います。
companiesに、企業名のみを格納した配列。
browsersに、Browsersに格納したいデータ群。
今回は上記のような仮データを用意しました。

companies.map((com, i) => {
    browsersMap.set(com, {
        mantainedBy: browsers[i].name,
        url: browsers[i].url,
        version: browsers[i].version
    });
})

companisをループし、keyにしています。
browsersに格納されているデータを順番にkeyに当てはめて入れています。

console.log(browsersMap.get('Google'))

最後に、keyを指定して、Browserの型に合わせたデータを取り出して出力しています。

やってることは、Map<string, string> とほとんど同じですが、
実際のデータを想定してみると、気持ちのいい書き方になりますね。

単純なオブジェクトとして格納する

上記でMapに格納し、取り出すことをやりましたが、Mapを使わずとも、key, valueの形で格納することはできます。

type Browsers = {
  [key: string]: {
    mantainedBy: string
    url: string
    version: number
  }
}

しかし、データ構造が複雑になればなるほど、取り出す時が大変になります。
純粋なkey, valueとしてのオブジェクトを作るのであればMapを使うのが良さそうです。

Discussion