TypeScriptで連想配列を使いこなす10の方法 – Japanシーモア

TypeScriptで連想配列を使いこなす10の方法

TypeScriptの連想配列を効果的に活用するイラストTypeScript
この記事は約23分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

TypeScriptを使う開発者として、データの構造として「連想配列」は避けて通れない存在です。

JavaScriptにおけるオブジェクトとしての利用方法をベースとして、TypeScriptでは型安全を持ち込むことで、より強力に、そして安全にデータを扱うことができます。

この記事では、TypeScriptでの連想配列の使い方を初心者から上級者までを対象に、10の具体的なサンプルコードを交えながら解説していきます。

また、注意点やカスタマイズ方法も詳細に掘り下げます。

連想配列とは、キーと値のペアでデータを管理する構造のことを指します。TypeScriptでは、これをより型の面で強化して扱うことが可能となっています。

例えば、キーの型や値の型を制約することができます。

この記事を通して、TypeScriptの連想配列を使いこなす技術を身につけて、より高度なプログラミングに挑戦してみてください。

●TypeScriptの連想配列とは

TypeScriptは、JavaScriptのスーパーセットとして知られ、より安全で堅牢なコードの記述を可能にする強力な機能を提供します。連想配列もその一つです。

JavaScriptのオブジェクトを基にしたものであり、キーと値のペアを保存する構造を持っています。

この記事では、TypeScriptの連想配列の概念とその詳細な使い方について詳しく解説していきます。

○連想配列の基本概念

連想配列は、文字列のキーとそれに関連する値を持つデータ構造です。

TypeScriptでは、連想配列は{ [key: string]: 値の型 }という形式で定義されることが一般的です。

例を見てみましょう。

このコードでは文字列をキーとし、数字を値とする連想配列を定義しています。

// 連想配列の定義
const fruits: { [key: string]: number } = {
  apple: 100,
  banana: 200,
  cherry: 150
};

この例では、fruitsという連想配列に果物の名前をキーとして、その価格を値として保存しています。

●連想配列の作り方

TypeScriptでは、JavaScriptのオブジェクトを基礎とした連想配列を利用することができます。

連想配列は、キーと値のペアを持つデータ構造です。

ここでは、TypeScriptでの連想配列の基本的な作り方を詳細に解説します。

○サンプルコード1:基本的な連想配列の定義

連想配列の定義は、オブジェクトリテラルの形式を利用します。

下記のサンプルコードは、TypeScriptでの連想配列の基本的な定義の方法を表しています。

// 連想配列の定義
let user: { [key: string]: string } = {
    name: "山田太郎",
    age: "25",
    job: "エンジニア"
};

このコードでは、userという変数名の連想配列を定義しています。

連想配列の型は{ [key: string]: string }という形式で、この型は「キーは文字列、値も文字列」という意味を持ちます。

具体的には、name, age, jobという3つのキーと、それに関連する値が定義されています。

この連想配列を利用することで、例えばuser.nameという形式で"山田太郎"という値にアクセスすることができます。

この例では、連想配列のキーと値は両方とも文字列としていますが、実際には数値やオブジェクトなど、さまざまな型の値を持たせることができます。

実際に上記のサンプルコードを実行すると、userという連想配列が定義され、その連想配列内のキーを利用して、それに対応する値にアクセスすることが可能となります。

このように、TypeScriptの連想配列は非常にシンプルに定義することができ、その後のコードでの操作も直感的です。

特に、TypeScriptの強力な型システムを活用することで、連想配列内のキーと値の型を厳格に管理することができるのが大きなメリットです。

○サンプルコード2:値の取得と設定

TypeScriptを使った連想配列では、簡単にキーに関連する値を取得したり、新しいキーと値のペアを設定することができます。

ここでは、連想配列の中から特定のキーに関連づけられた値を取得する方法や、新しいキーと値を設定する方法を詳しく解説していきます。

まず、連想配列の値を取得するには、そのキーを指定してアクセスします。

キーを使って値を取得するには、ドット記法またはブラケット記法のいずれかを使用することができます。

例として、次の連想配列を考えます。

let user = {
    name: "山田太郎",
    age: 30,
    city: "東京"
};

この連想配列からnameの値を取得する場合、次のようにします。

let userName = user.name;  // ドット記法
let userNameBracket = user["name"];  // ブラケット記法

このコードではnameを使ってuser連想配列から値を取得しています。

この例では山田太郎が取得されることとなります。

さらに、連想配列に新しいキーと値を設定する場合、または既存のキーの値を変更する場合、ブラケット記法を使用します。

新しいキーcountryとその値日本を上記のuser連想配列に追加する場合、次のように記述します。

user["country"] = "日本";

このコードではcountryというキーを使用して、user連想配列に日本という値を設定しています。

これを行った後、userの内容を見ると、新しいキーと値のペアが追加されていることがわかります。

また、既存のキーの値を変更する場合も同様の方法で変更を行います。

例えば、ageの値を31に変更する場合は次のように記述します。

user["age"] = 31;

これで、userageの値は31に更新されます。

○サンプルコード3:連想配列のキーと値を繰り返し取得

TypeScriptで連想配列を扱う際、そのキーと値を繰り返し取得する方法を学ぶことは非常に実践的です。

この手法を使うことで、連想配列の内容を一覧表示したり、特定の条件に合致する要素を検索したりする際に役立ちます。

下記のサンプルコードでは、連想配列のキーと値を順に取得して、それぞれコンソールに出力しています。

// 連想配列の定義
let fruitsPrices: { [key: string]: number } = {
  "りんご": 100,
  "バナナ": 80,
  "みかん": 50
};

// 連想配列のキーと値を繰り返し取得
for (let key in fruitsPrices) {
    if (fruitsPrices.hasOwnProperty(key)) {
        console.log(`キー:${key}, 値:${fruitsPrices[key]}円`);
    }
}

このコードでは、fruitsPricesという名前の連想配列を使って、果物の名前をキーとし、その価格を値として保存しています。

続いて、for-in文を使用して連想配列のキーを一つずつ取得し、それを使って連想配列の値も同時に取得しています。

そして、取得したキーと値をテンプレートリテラルを利用して整形し、コンソールに出力しています。

このサンプルコードを実行すると、次のような結果が得られるでしょう。

りんごの価格は100円、バナナの価格は80円、みかんの価格は50円という具体的な情報が順番に表示されます。

これによって、連想配列の中身を確認することができ、さらに特定の処理を行うための基盤としても利用することができます。

ただし、連想配列を繰り返し取得する際の注意点として、for-in文内でhasOwnPropertyメソッドを使用して、取得したキーが連想配列の独自のプロパティであることを確認しています。

これは、プロトタイプチェーンから継承されたプロパティを無視するためのものです。

この確認を省略すると、予期しないプロパティも取得してしまう可能性がありますので注意が必要です。

●連想配列の詳細な使い方

TypeScriptを用いて連想配列を操作する際の、さらに詳しい方法を探求します。

連想配列は、キーと値のペアを持つデータ構造であり、ここではそのより高度な使い方を解説します。

○サンプルコード4:キーの存在確認

連想配列に特定のキーが存在するかどうかを確認する場面は頻繁にあります。

TypeScriptではin演算子を使って、キーの存在を簡単に確認することができます。

const studentScores: { [key: string]: number } = {
  Taro: 85,
  Hanako: 90,
  Jiro: 78,
};

if ('Taro' in studentScores) {
  console.log('Taroのスコアは存在します。');
} else {
  console.log('Taroのスコアは存在しません。');
}

このコードでは、連想配列studentScoresを使って、Taroというキーが存在するかどうかを確認しています。

存在していれば、’Taroのスコアは存在します。’というメッセージが表示されます。

キーの存在を確認することで、その後の処理でキーに関連する値を安全に取得することができます。

実際に上記のコードを実行すると、コンソールには’Taroのスコアは存在します。’と表示されます。なぜなら、studentScoresにはTaroというキーが存在するからです。

○サンプルコード5:キーの削除

連想配列の利点の一つは、特定のキーとそれに関連づけられた値を簡単に管理できる点です。

しかし、時として特定のキーを削除する必要が生じる場面も考えられます。

TypeScriptの連想配列からキーを削除する方法について、詳しく説明します。

このコードでは、deleteオペレータを使って連想配列からキーを削除しています。

この例では、userという連想配列からageというキーを削除しています。

let user: { [key: string]: any } = {
    name: "Taro",
    age: 25,
    country: "Japan"
};

// ageキーを削除
delete user.age;

console.log(user);

コメントを参考にしながら、上記のコードをTypeScriptで実行すると、user連想配列からageキーが確かに削除されることがわかります。

その結果、user連想配列は{ name: "Taro", country: "Japan" }となります。

deleteオペレータは、オブジェクトのプロパティを削除するためのものですが、連想配列も実質的にはオブジェクトなので、この方法でキーを削除することができます。

ただし、キーの削除操作は、元の連想配列オブジェクトを変更します。

そのため、オブジェクトの元の状態を保持したい場合は、削除操作前にディープコピーなどの方法でバックアップを取ることをおすすめします。

さて、実際にキーを削除することの利点として、不要なデータを削除してオブジェクトの容量を節約する、特定のキーの存在を意図的に隠すなどの操作が考えられます。

一方、注意点としては、一度削除したキーは元に戻すことができないため、削除操作を行う前に十分な確認が必要です。

○サンプルコード6:連想配列のマージ

連想配列を使う際、異なる連想配列を統合したい場面がよくあります。TypeScriptでは、これを簡単に実現できる方法があります。

今回は、2つの連想配列をマージする方法をサンプルコードとともに詳しく解説していきます。

このコードでは、Object.assignメソッドを使って、2つの連想配列を統合しています。

この例では、firstObjsecondObjの2つの連想配列を統合して、新しい連想配列mergedObjを作成しています。

// 2つの連想配列を定義
const firstObj = {
  key1: "value1",
  key2: "value2"
};

const secondObj = {
  key3: "value3",
  key4: "value4"
};

// 2つの連想配列をマージ
const mergedObj = Object.assign({}, firstObj, secondObj);

// マージされた連想配列を表示
console.log(mergedObj);  // 出力: { key1: 'value1', key2: 'value2', key3: 'value3', key4: 'value4' }

Object.assignメソッドを利用すると、複数のソースオブジェクトをターゲットオブジェクトにコピーすることができます。

この例では、まず空のオブジェクト({})を作成し、その後にfirstObjsecondObjの順番でマージしています。

その結果、新しく作成されたmergedObjには、両方の連想配列のキーと値が格納されます。

この方法には注意が必要です。

もしマージする連想配列に同じキーが存在した場合、後から指定された連想配列の値で上書きされます。

例えば、firstObjkey3が存在し、その値が"oldValue"であった場合、マージ後のmergedObjkey3の値は"value3"になります。

この挙動は予期しない結果を生む可能性があるため、マージを行う際には十分な注意が必要です。

また、TypeScriptのバージョン3.7以降では、スプレッド構文を使用しても連想配列をマージすることができます。

スプレッド構文を使うと、よりシンプルに連想配列を統合できるため、以下のようなコードもよく使用されます。

const mergedObjWithSpread = { ...firstObj, ...secondObj };
console.log(mergedObjWithSpread);  // 出力: { key1: 'value1', key2: 'value2', key3: 'value3', key4: 'value4' }

このコードでは、スプレッド構文を使ってfirstObjsecondObjを新しい連想配列mergedObjWithSpreadにマージしています。

この方法も、先ほどのObject.assignメソッドと同様の注意点がありますので、同じキーの存在に注意しながら使用してください。

●連想配列の応用例

連想配列はその基本的な操作だけでなく、様々な応用的な使い方も可能です。

特にTypeScriptを利用することで、型の安全性を保ったまま、より高度な操作が行えるようになります。

今回は、その応用的な使い方の一例として、連想配列のフィルタリングやソートに関するサンプルコードをご紹介します。

○サンプルコード7:フィルタリングとソート

連想配列の中から特定の条件を満たす要素のみを取り出すフィルタリングと、特定のルールに基づいて要素を並べ替えるソートは、連想配列を操作する際の基本的なテクニックです。

// 連想配列の定義
const members: { [key: string]: number } = {
  "田中": 25,
  "鈴木": 30,
  "佐藤": 28,
  "山田": 22,
};

// 25歳以上のメンバーのみをフィルタリング
const filteredMembers: { [key: string]: number } = {};
for (const [name, age] of Object.entries(members)) {
  if (age >= 25) {
    filteredMembers[name] = age;
  }
}

// 年齢でソート
const sortedMembersArray = Object.entries(filteredMembers).sort((a, b) => a[1] - b[1]);
const sortedMembers: { [key: string]: number } = {};
sortedMembersArray.forEach(([name, age]) => {
  sortedMembers[name] = age;
});

このコードでは、まずmembersという連想配列を定義しています。

この連想配列には名前と年齢がキーと値として格納されています。

次に、Object.entriesを使って連想配列の各要素を繰り返し処理しています。

この例では、年齢が25歳以上のメンバーのみをfilteredMembersという新しい連想配列に格納しています。

そして、このフィルタリングされた連想配列を年齢順にソートします。

Object.entriesを使用して連想配列を配列に変換し、その配列をsortメソッドでソートしています。

ソートの結果、sortedMembersArrayは年齢でソートされた配列となり、これをもとにsortedMembersという連想配列を再構築します。

実際に上記のコードを実行すると、25歳以上のメンバーが年齢順にソートされたsortedMembersという連想配列を得ることができます。

この例を参考に、実際のプロジェクトでの連想配列の操作に役立ててみてください。

○サンプルコード8:キーと値を逆転させる

連想配列を扱う上で時としてキーと値の位置を逆転させたいケースが出てきます。

この操作は、特定の状況でデータの再整形が必要となる際に非常に役立ちます。

TypeScriptではこの操作も簡単に行うことができます。

このコードでは、Object.entriesを使って連想配列のキーと値を取得し、その後、reduceメソッドを活用してキーと値を逆転させています。

この例では、初めに定義した連想配列のキーと値を逆転させた新しい連想配列を生成しています。

const original = {
    "name": "Taro",
    "age": "25",
    "country": "Japan"
};

const reversed = Object.entries(original).reduce((acc, [key, value]) => {
    acc[value] = key;
    return acc;
}, {} as { [key: string]: string });

console.log(reversed);

上記のコードを実行すると、次のような出力が得られます。

キーと値が逆転された連想配列が生成されているのがわかります。

{
    "Taro": "name",
    "25": "age",
    "Japan": "country"
}

この方法を使用する際のポイントは、キーと値が逆転することにより、元の連想配列の値が一意である必要があるという点です。

もし元の連想配列の値が一意でない場合、逆転後の連想配列でキーの重複が発生し、期待しない動作となる可能性があります。

例えば、次のような連想配列があった場合、

const nonUnique = {
    "name1": "Taro",
    "name2": "Taro",
    "country": "Japan"
};

キーと値を逆転させると、”Taro”というキーが2つ存在することとなり、後から来る値で上書きされてしまいます。

このようなケースを避けるためには、あらかじめ連想配列の値が一意であるかどうかを確認する必要があります。

○サンプルコード9:連想配列を配列に変換

TypeScriptにおいて、連想配列は非常に役立つデータ構造の一つですが、特定の状況では連想配列のキーや値を通常の配列に変換したい場面が出てきます。

例えば、キーの一覧や値の一覧を取得する場合などが挙げられます。

では、実際にTypeScriptで連想配列から配列への変換を行う方法について、詳しく解説していきましょう。

// 連想配列の定義
let userScores: {[key: string]: number} = {
    "山田": 90,
    "佐藤": 80,
    "鈴木": 85
};

// キーの配列を取得
let keysArray: string[] = Object.keys(userScores);

// 値の配列を取得
let valuesArray: number[] = Object.values(userScores);

// [キー, 値]のペアを持つ配列を取得
let entriesArray: [string, number][] = Object.entries(userScores);

// コンソールに出力して結果を確認
console.log(keysArray); // ["山田", "佐藤", "鈴木"]
console.log(valuesArray); // [90, 80, 85]
console.log(entriesArray); // [["山田", 90], ["佐藤", 80], ["鈴木", 85]]

このコードでは、まずuserScoresという連想配列を定義しています。

この連想配列には、ユーザー名をキーとし、それに関連するスコアを値としています。

連想配列からキーのみを取得するにはObject.keysメソッドを使用します。

この例では、結果として["山田", "佐藤", "鈴木"]という文字列の配列を得られます。

また、連想配列の値のみを取得する場合はObject.valuesメソッドを利用します。

この方法で、[90, 80, 85]という数値の配列が取得できます。

さらに、Object.entriesメソッドを使うことで、キーと値のペアを2要素の配列として取得することができます。

この例でいうと、[["山田", 90], ["佐藤", 80], ["鈴木", 85]]という配列を得られます。

実際に上記のコードを実行すると、コンソールにそれぞれの配列が出力されます。

出力される結果は、["山田", "佐藤", "鈴木"][90, 80, 85]、そして[["山田", 90], ["佐藤", 80], ["鈴木", 85]]となります。

○サンプルコード10:連想配列のネスト

TypeScriptの連想配列の機能を最大限に活用するためには、連想配列のネストを理解することが不可欠です。

連想配列のネストとは、連想配列の中に別の連想配列を含めることを指します。

このような構造を持つ連想配列は、多次元のデータ構造や、より複雑なデータを管理する際に非常に便利です。

例として、社員の情報を持つ連想配列を考えてみましょう。

各社員の情報には、名前や年齢の他に、住所情報も含まれているとします。

この住所情報もまた、都道府県、市区町村、番地などの複数の情報から成り立っています。

このような複雑なデータ構造を、連想配列のネストを使って表現することができます。

この概念を具体的なサンプルコードで紹介します。

type Address = {
  prefecture: string;
  city: string;
  addressLine: string;
};

type Employee = {
  name: string;
  age: number;
  address: Address;
};

const employeeInfo: Employee = {
  name: "田中太郎",
  age: 30,
  address: {
    prefecture: "東京都",
    city: "新宿区",
    addressLine: "西新宿1-1-1"
  }
};

console.log(employeeInfo.name);          // 田中太郎
console.log(employeeInfo.address.city);  // 新宿区

このコードでは、Employeeという型を定義しています。

この型は名前、年齢、そしてAddressという型のaddressというキーを持つ連想配列です。

さらに、Addressは都道府県、市区町村、番地という3つのキーを持つ連想配列として定義されています。

このように、一つの連想配列の中に別の連想配列をネストする形でデータを表現することができます。

この例で表したように、連想配列のネストを活用することで、複雑なデータ構造を簡潔に、かつ型安全に管理することができます。

以上のサンプルコードを実行すると、コンソールには「田中太郎」と「新宿区」という2つの出力が表示されることが確認できます。

このように、ネストされた連想配列のキーにアクセスする際には、.(ドット)を連続して使用して各キーを指定します。

●注意点と対処法

TypeScriptの連想配列を使ってプログラムを書く際、注意すべきポイントやミスを避けるための対処法を取り上げます。

○変更不可な連想配列の作成

TypeScriptでは、readonly修飾子を使用することで、変更不可な連想配列を作成できます。

これは、一度定義した連想配列の内容を後から変更できないようにするためのものです。

type ReadonlyPerson = {
    readonly [key: string]: string;
};

const person: ReadonlyPerson = {
    name: "田中太郎",
    age: "25"
};

// person.age = "26"; // この行はエラーとなります。

このコードではReadonlyPersonという型を定義しており、その中のすべてのキーと値はreadonlyとして扱われます。

したがって、personageを後から変更しようとすると、TypeScriptのコンパイラはエラーを返します。

○undefinedとの取り扱い

連想配列で指定したキーが存在しない場合、その値はundefinedとなります。

これは意図しない結果を生む可能性があるため、注意が必要です。

const colors = {
    red: "赤",
    blue: "青",
    green: "緑"
};

console.log(colors["yellow"]); // undefined

上記の例でyellowというキーは連想配列colorsに存在しないため、結果としてundefinedが出力されます。

これを避ける方法の一つとして、キーの存在を事前に確認する方法があります。

if ("yellow" in colors) {
    console.log(colors["yellow"]);
} else {
    console.log("指定された色は存在しません。");
}

こちらの方法では、in演算子を使ってキーの存在を確認しています。

存在しない場合には、適切なメッセージを出力することができます。

●カスタマイズ方法

TypeScriptの連想配列は非常に柔軟性が高く、様々なカスタマイズが可能です。

特に型システムを活用することで、連想配列のキーと値の型を厳格に管理することができ、バグを予防しながら効率的なコーディングが実現できます。

○型のカスタマイズと活用

TypeScriptは、連想配列のキーと値の型をカスタマイズできるという大きな利点を持っています。

具体的には、特定のキーに対して特定の型の値のみを許容するような連想配列を定義することができます。

このコードでは、連想配列のキーとして「name」と「age」のみを許容し、それぞれのキーに対応する値の型も指定しています。

この例では、「name」は文字列型、「age」は数値型として定義しています。

type CustomMap = {
    name: string;
    age: number;
};

const person: CustomMap = {
    name: '山田太郎',
    age: 25
};

// person.job = "developer"; // この行はエラーになります。

上記の連想配列「person」には、許可されていないキー「job」を追加することはできません。

このように、連想配列の型をカスタマイズすることで、不正なキーの追加や、期待しない型の値の設定を防ぐことができます。

また、Optionalなキーも指定することができます。

下記の例では、キー「gender」は存在しないことも許容されています。

type CustomMapOptional = {
    name: string;
    age: number;
    gender?: string;
};

const personOptional: CustomMapOptional = {
    name: '山田花子',
    age: 30
};

// もし後でgenderを追加したければ、次のように追加することができます。
personOptional.gender = '女性';

この例のように、「gender」キーはOptionalなため、連想配列の初期定義時には存在しなくてもエラーになりません。

しかし、後から追加することも可能です。

実際に上記のコードを実行すると、連想配列「personOptional」は「name」、「age」、そして「gender」の3つのキーを持つオブジェクトとして定義されます。

まとめ

この記事では、TypeScriptの連想配列を効果的に使用するための詳細な方法とサンプルコードを紹介しました。

連想配列の基本的な定義から、応用的な使い方、さらに注意点やカスタマイズの方法までを網羅的に解説してきました。

連想配列は、TypeScriptを使用する上で避けては通れない要素の一つです。

この記事で紹介した方法やサンプルコードを参考に、TypeScriptの連想配列を効果的に活用し、より高品質なコードを書いていきましょう。