# 辞書 | Dictionary型
辞書とは、キーと値のペアで構成され、順序を持たないコレクションです。各値は一意のキーに関連付けられ、キーは辞書内でその値の識別子として機能します。配列とは異なり、辞書内の項目には指定された順序はありません。Swiftでは、Dictionary<Key, Value>型
で辞書を表現します。
# 辞書の宣言方法
Swiftの辞書は次のフォーマットで書くことができます。
let dictionay: Dictionary<Keyの型, Valueの型> = ["キー名": 値]
次の例では、キーをString型、値にInt型を持つ辞書を定義しています。
let a: Dictionary<String, Int> = ["key": 1, "key2": 2]
# シンタックシュガー
Dictionary<String, Int>
の型アノテーションは、シンタックシュガーを使って、[キーの型: 値の型]
で書くことができます。
let a: [String: Int] = ["key": 1, "key2": 2]
一般的に、シンタックスシュガーが使われることが多いです。
# 型推論
Swiftは、辞書に含むキーと値から型を推論できるので、宣言時には型を省略して書くことができます。前節の例を型アノテーションを省略して書くと、次のようになります。
let a = ["key": 1, "key2": 2]
しかし、空の辞書の場合は、値の型推論ができないため、明示的に型アノテーションを指定する必要があります。
let a: [String: Int] = [:]
# 空の辞書
空の辞書をイニシャライザを使って、次のように書くこともできます。
let a = [String: Int]()
# 辞書の特徴
Swiftの辞書の特徴は以下になります。
# キーは一意にならなければならない
キーはコレクションの中で、他のキーと被らないようにしなければなりません。
同じキーを指定した場合は、実行時エラーになります。
let a: [String: Int] = ["key": 1, "key": 2]
/* 実行結果 */
// Fatal error: Dictionary literal contains duplicate keys
// Current stack trace:
# 順序関係は保証されない
辞書は、繰り返される要素の順番を保証しません。
for-in文で、繰り返し処理を実行すると、実行環境によってその順番が変わります。
let dictionary = ["1":10, "2":20, "3":30, "4":40, "5":50]
for (key, value) in dictionary {
print("\(key): \(value)")
}
// 実行環境によって順番は変わる
// 1回目
// 4: 40
// 1: 10
// 2: 20
// 5: 50
// 3: 30
// 2回目
// 2: 20
// 1: 10
// 3: 30
// 4: 40
// 5: 50
順番を保証したい場合は、KeyValuePairs
型 を使用してください。
(Swift5.0 以前は DictionaryLiteral
という名称でしたがSwift5.0以降では、KeyValuePairs
という名前になりました。)
// KeyValuePairs型を指定する
let dictionary: KeyValuePairs = ["1":10, "2":20, "3":30, "4":40, "5":50]
for (key, value) in dictionary {
print("\(key): \(value)")
}
// 1回目
// 1: 10
// 2: 20
// 3: 30
// 4: 40
// 5: 50
// 2回目
// 1: 10
// 2: 20
// 3: 30
// 4: 40
// 5: 50
# 値へのアクセス
辞書の値へアクセスするには、辞書[キー名]
のフォーマットでキー名を指定すると、取得することができます。
let a = ["key": 1, "key2": 2]
let b = a["key"] // Optional(1)
存在しないキー名を指定すると、nilが返ってきます。
let a = ["key": 1, "key2": 2]
let b = a["key3"] // nil
nilになりうる値は Optional型 になります。そのため、辞書へアクセスして取り出した値は、Optional型で返ってきます。
# 値の更新
辞書の値を更新するには、更新したい値のキー名を指定して値を代入すると、更新することができます。
var a = ["key": 1, "key2": 2]
a["key"] = 100
a // ["key": 100, "key2": 2]
定数の let
で宣言すると、代入が不可になるのでコンパイラエラーになります。
let a = ["key": 1, "key2": 2]
a["key"] = 100
/* 実行結果 */
// error: cannot assign through subscript: 'a' is a 'let' constant
// a["key"] = 100
// note: change 'let' to 'var' to make it mutable
// let a = ["key": 1, "key2": 2]
# 値の追加
辞書の要素を追加するには、追加したい値のキー名を指定して値を代入すると、追加することができます。
var a = ["key": 1, "key2": 2]
a["key3"] = 3
a // ["key": 1, "key3": 3, "key2": 2]
# 値の削除
辞書の要素を削除するには、追加したい値のキー名を指定して nil
を代入すると、削除することができます。
var a = ["key": 1, "key2": 2]
a["key"] = nil
a // ["key2": 2]
# removeValue
removeValue
も同様に辞書の要素を削除することができます。削除対象の要素が存在すれば、削除した値を返します。もし存在しなければnilを返します。
var a = ["key": 1, "key2": 2]
let removed = a.removeValue(forKey: "key")
removed // Optional(1)
a // ["key2": 2]
# その他の使い方
# グループ化する
与えられたキーを元に配列などのSequenceからグループ化された辞書を生成することができます。初期化する際に、grouping
と by
引数を指定してグループ化させます。
次の例では、生徒をクラスごとに分類してグループ化しています。grouping
には対象の配列を渡し、by
にはグループ化させるキーを指定します。
struct Student {
var name: String
var className: String
}
let students = [
Student(name: "Taro", className: "A"),
Student(name: "Jiro", className: "B"),
Student(name: "Saburo", className: "C"),
Student(name: "Shiro", className: "A"),
Student(name: "Goro", className: "C"),
]
let grouped = Dictionary(grouping: students, by: { $0.className })
grouped["A"] // [{name "Taro", className "A"}, {name "Shiro", className "A"}]
← 配列 | Array型 集合 | Set型 →