Swiftで連想配列を扱おう!10選の詳細なサンプルコードと応用例

Swiftの連想配列のイラストとサンプルコードのスクリーンショットSwift
この記事は約15分で読めます。

 

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

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

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

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

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

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

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

はじめに

この記事を読めばSwiftの連想配列を使ったプログラムを作成することができるようになります。

SwiftはAppleが開発したプログラミング言語で、iOSやMacのアプリケーションを作成する際に用いられます。

その中でも「連想配列」と呼ばれるデータ構造は、データを効率的に管理するための重要な要素となっています。

この記事では、Swiftの連想配列、正式には「Dictionary」の基本的な使い方から応用例まで、わかりやすく詳しく解説します。

Swiftの連想配列について知らない方、あるいはより深く知りたいと考えている方、必ず役立つ情報が詰まっていますので、ぜひ最後までお読みください。

●Swiftの連想配列(Dictionary)とは

連想配列は、キーとバリューのペアでデータを格納するコレクションです。

他の言語では「ハッシュマップ」とも呼ばれることが多いのですが、Swiftでは「Dictionary」と呼ばれています。

例えば、都道府県とその都道府県の人口を管理したい場合、連想配列を使用すると非常に効率的にデータを扱うことができます。

キーに都道府県名、バリューに人口数を指定することで、都道府県名から人口数を瞬時に取得することができるのです。

SwiftのDictionaryは非常に強力で、型安全を保持しています。

これは、宣言時にキーとバリューの型を明示的に指定することで、間違った型のデータを格納しようとした場合にコンパイルエラーとして検出されるという意味です。

この機能により、バグを未然に防ぐことができます。

○Dictionaryの基本概念

SwiftにおけるDictionaryは、次のように宣言されます。

var dictionaryName: [KeyType: ValueType] = [:]

ここで、KeyTypeはキーの型、ValueTypeはバリューの型を指定します。

例えば、キーがString型で、バリューがInt型の場合、以下のように宣言できます。

var populationOfPrefecture: [String: Int] = [:]

この例では、都道府県名をキーとして、人口数をバリューとする連想配列を宣言しています。

また、[:]は空の連想配列を表しています。

●連想配列の基本的な使い方

Swiftの連想配列、つまりDictionaryは、キーとバリューの組み合わせでデータを格納するコレクション型です。

ここでは、その基本的な使い方を詳しく解説していきます。

○サンプルコード1:連想配列の宣言と初期化

Swiftの連想配列は、キーの型とバリューの型を明示的に指定して宣言します。

下記のコードは、キーがString型、バリューがInt型の空の連想配列を宣言し、初期化しています。

var populationOfPrefecture: [String: Int] = [:]

このコードでは、都道府県名をキーとして、その都道府県の人口をバリューとする連想配列を準備しています。

○サンプルコード2:連想配列からのデータの取得

連想配列にデータを格納した後、特定のキーに対応するバリューを取得する方法を見ていきましょう。

下記のサンプルコードでは、東京都と大阪府の人口を連想配列に追加し、その後東京都の人口を取得しています。

populationOfPrefecture["東京都"] = 13515271
populationOfPrefecture["大阪府"] = 8823452

if let tokyoPopulation = populationOfPrefecture["東京都"] {
    print("東京都の人口は、\(tokyoPopulation)人です。")
}

この例では、連想配列からデータを取得する際に、オプショナルバインディングを用いています。

これにより、指定したキーが連想配列に存在しない場合に備えることができます。

○サンプルコード3:連想配列にデータを追加する

連想配列に新たなデータを追加する方法を見ていきましょう。

下記のコードは、神奈川県の人口を連想配列に追加しています。

populationOfPrefecture["神奈川県"] = 9145572

この方法を用いることで、新しいキーとバリューのペアを連想配列に簡単に追加することができます。

●連想配列の応用例

Swiftの連想配列は、基本的な操作だけでなく、さまざまな応用例も持っています。

ここでは、連想配列を使ったデータのフィルタリングやソートといった高度な操作の方法を詳しく解説していきます。

○サンプルコード4:連想配列を使ったデータのフィルタリング

連想配列のデータをフィルタリングする場合、Swiftの高階関数を使用することで簡潔に書くことができます。

下記のコードは、人口が1000万人以上の都道府県のみを取り出す例です。

let largePopulationPrefectures = populationOfPrefecture.filter { $1 >= 10000000 }

このコードでは、連想配列のfilterメソッドを使用して、バリューが1000万人以上の都道府県を取得しています。

○サンプルコード5:連想配列内のデータをソートする

連想配列のデータをキーやバリューでソートする場合も、Swiftの高階関数を活用できます。

下記のサンプルコードでは、都道府県の人口で降順にソートしています。

let sortedByPopulation = populationOfPrefecture.sorted { $0.value > $1.value }

このコードでは、sortedメソッドを用いて、バリューの人口を基準にして、大きいものから小さいものへと降順にソートしています。

○サンプルコード6:連想配列と関数を組み合わせた使用例

連想配列は単体での操作だけでなく、関数と組み合わせることでさらに強力な処理を実現することができます。

関数と連想配列を組み合わせることで、例えば特定の条件に合致するデータを抽出したり、変換したりすることが容易になります。

下記のサンプルコードでは、連想配列内のデータを与えられた関数を利用して加工する一例を表しています。

このコードでは、各都道府県の人口を2倍にする関数を作成し、それを連想配列の各要素に適用しています。

let populationOfPrefecture = ["東京": 13515271, "大阪": 8839469, "愛知": 7483128]

// 人口を2倍にする関数
func doublePopulation(of number: Int) -> Int {
    return number * 2
}

let doubledPopulation = populationOfPrefecture.mapValues(doublePopulation)

このコードでは、連想配列のmapValuesメソッドを使用して、doublePopulation関数を各バリューに適用しています。

結果として、doubledPopulationの中身は["東京": 27030542, "大阪": 17678938, "愛知": 14966256]となり、各都道府県の人口が2倍になった新しい連想配列が得られます。

○サンプルコード7:複雑なデータ構造の連想配列の利用

Swiftの連想配列は、キーとバリューのペアでデータを管理することができるため、複雑なデータ構造を持つ情報も格納することが可能です。

ここでは、都道府県ごとに複数の都市の人口を持つ連想配列の例を紹介します。

let prefectureCities = [
    "東京": ["新宿": 339211, "渋谷": 217667],
    "大阪": ["大阪市": 2694086, "堺市": 835839]
]

// 東京の新宿区の人口を取得
if let shinjukuPopulation = prefectureCities["東京"]?["新宿"] {
    print("新宿区の人口は\(shinjukuPopulation)人です。")
}

この連想配列のキーは都道府県名で、対応するバリューはその都道府県に属する都市とその都市の人口を持つ別の連想配列となっています。

このように、連想配列のバリュー部分にさらに連想配列を持たせることで、階層的なデータ構造を作成することができます。

上記のサンプルコードの最後の部分では、オプショナルチェイニングを利用して、新宿区の人口を安全に取得しています。

○サンプルコード8:連想配列を使用したJSONの操作

近年、データのやり取りや保存の際にJSON形式が頻繁に使用されるようになりました。

Swiftでも、JSON形式のデータとの相互変換をサポートする機能が提供されています。

連想配列とJSONの関係は非常に密接で、SwiftのDictionary型とJSONオブジェクトは、構造的に非常に似ています。

ここでは、SwiftでのJSONデータの読み込みと、それを連想配列として操作する方法を紹介します。

このコードでは、JSON形式の文字列を取得し、それを連想配列に変換しています。

変換後の連想配列を利用して、特定のデータにアクセスする例も示します。

import Foundation

let jsonData = """
{
    "名前": "田中",
    "年齢": 25,
    "住所": {
        "都道府県": "東京",
        "市区町村": "新宿区"
    }
}
""".data(using: .utf8)!

do {
    // JSONデータを連想配列に変換
    if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
        // 名前のデータを取得
        if let name = jsonObject["名前"] as? String {
            print("名前は\(name)です。")
        }
        // 住所のデータを連想配列として取得
        if let address = jsonObject["住所"] as? [String: String], let prefecture = address["都道府県"] {
            print("都道府県は\(prefecture)です。")
        }
    }
} catch {
    print("JSONの変換に失敗しました。")
}

このコードでは、まずJSON形式の文字列をData型に変換しています。

その後、JSONSerialization.jsonObject(with:options:)メソッドを使用して、このJSONデータを連想配列に変換しています。

変換後は、連想配列としてデータにアクセスできるため、名前や住所などの情報を取得しています。

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

名前は田中です。
都道府県は東京です。

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

連想配列の中に連想配列を含めることで、より複雑なデータ構造を表現することができます。

このように連想配列の中に連想配列を持つことを「ネスト」と言います。

下記のサンプルコードでは、ユーザーのプロフィール情報をネストした連想配列で表現しています。

let userProfile: [String: Any] = [
    "ID": 12345,
    "名前": "佐藤",
    "連絡先": [
        "メール": "sato@example.com",
        "電話": "090-1234-5678"
    ]
]

// 連絡先のメールアドレスを取得
if let contact = userProfile["連絡先"] as? [String: String], let email = contact["メール"] {
    print("メールアドレスは\(email)です。")
}

このコードでは、連絡先というキーに対して、メールアドレスや電話番号などの連絡先情報を格納した連想配列をネストしています。

このようにネストを利用することで、関連する情報をまとめて格納することができ、データの取り扱いがより直感的になります。

コードを実行すると、メールアドレスの情報が取得でき、次のように表示されます。

メールアドレスはsato@example.comです。

○サンプルコード10:連想配列を使用したアルゴリズムの実装

連想配列はアルゴリズムの実装にも非常に有用です。

特に、データの出現回数を数えるような場面では連想配列の利用が欠かせません。

下記のサンプルコードは、与えられた文字列の中で各文字の出現回数を数えるアルゴリズムを表しています。

let inputString = "programming"
var characterCount: [Character: Int] = [:]

for char in inputString {
    characterCount[char, default: 0] += 1
}

for (char, count) in characterCount {
    print("\(char): \(count)回")
}

このコードでは、まず文字ごとの出現回数を保持するための連想配列characterCountを用意しています。

次に、与えられた文字列inputStringの各文字を順に調べ、連想配列を更新しています。

このコードを実行すると、各文字の出現回数が次のように表示されます。

p: 1回
r: 2回
o: 1回
g: 2回
a: 1回
m: 2回
i: 1回

●注意点と対処法

Swiftの連想配列(Dictionary)を使用する際には、いくつかの注意点やその対処法を知っておくことが重要です。

これにより、より効率的でバグの少ないコーディングを実現することができます。

○連想配列のキーについての注意

連想配列のキーはユニークである必要があります。

もし同じキーで新しい値を設定すると、前の値は上書きされてしまいます。

これは意図しないデータの上書きを引き起こす可能性があるため、注意が必要です。

このコードでは、既存のキーに対して新しい値を設定する方法を紹介しています。

この例では、キー”apple”に対する値が上書きされます。

var fruits = ["apple": 100, "banana": 150]
fruits["apple"] = 120
print(fruits) // ["apple": 120, "banana": 150]

もし意図的に値を上書きする場合以外で、既存のキーに新しい値を設定してしまったときの対策として、キーの存在チェックを行うことが考えられます。

if fruits["apple"] == nil {
    fruits["apple"] = 120
}

この方法で、キー”apple”が存在しない場合のみ新しい値が設定されます。

○型の異なる値を持つ連想配列の取り扱い

Swiftは静的型付けの言語であり、連想配列も特定の型のキーと値のペアを保持することが前提となっています。

しかし、場合によっては、異なる型の値を持つ連想配列を取り扱いたいことがあります。

このコードでは、Any型を使用して、異なる型の値を持つ連想配列の作成方法を紹介しています。

この例では、文字列と整数の値を持つ連想配列を作成しています。

var mixedValues: [String: Any] = ["name": "山田", "age": 30]

しかし、このような連想配列を使用する際には、値を取り出すときに型キャストが必要となります。

このため、事前にどのような型の値が格納されているのかを知っていることが前提となります。

if let name = mixedValues["name"] as? String {
    print("名前は\(name)です。")
}

このコードでは、”name”キーの値をString型として取り出しています。

このような型キャストは、安全に値を取り出すための重要な手段となります。

●カスタマイズ方法

Swiftでの連想配列(Dictionary)は非常に便利なデータ構造ですが、標準の機能だけでは不十分な場面もあるかもしれません。

そういった場合、Swiftの強力な拡張機能を活用して、連想配列に独自のメソッドやプロパティを追加することが可能です。

ここでは、そのようなカスタマイズ方法をいくつか紹介していきます。

○連想配列の拡張機能の実装

連想配列に新しい機能を追加するための基本的な手法として、Swiftの「extension」を利用します。

これにより、既存の型に新しいメソッドやプロパティを追加することができます。

このコードでは、Dictionary型を拡張して、キーと値を逆転させるメソッドを追加する方法を紹介しています。

この例では、キーと値を逆転させた新しい連想配列を返すメソッドを実装しています。

extension Dictionary where Value: Hashable {
    func reverseKeyValue() -> [Value: Key] {
        var reversedDictionary = [Value: Key]()
        for (key, value) in self {
            reversedDictionary[value] = key
        }
        return reversedDictionary
    }
}

let sampleDict = ["a": 1, "b": 2, "c": 3]
let reversed = sampleDict.reverseKeyValue()
print(reversed) // [1: "a", 2: "b", 3: "c"]

上記のコードで、reverseKeyValueという新しいメソッドをDictionary型に追加しました。

このメソッドを使用することで、キーと値を逆転させた新しい連想配列を簡単に取得することができます。

まとめ

Swiftの連想配列(Dictionary)は、キーと値の組み合わせでデータを保存・操作するための強力なデータ構造です。

この記事では、連想配列の基本的な使い方から応用、さらにはカスタマイズ方法までを詳細に解説しました。

これにより、データの保存や取得、操作といった多岐にわたるタスクを効率的に行うことができるようになります。

初心者の方でもステップバイステップで学ぶことができるように、各項目ごとにサンプルコードを交えながらの詳細な解説を行いました。

これらの知識を元に、Swiftでのアプリ開発やデータ処理の際の参考にしていただければ幸いです。