TypeScriptで積極的にMapを使おう。
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