この記事ではSwift
の基本ある、辞書
についての基本事項を解説していきます。
プログラミングが初心者も、他の言語をやっていてSwift
は初心者という人にもわかるように説明していきたいと思います。
サンプルコードも交えながら説明していきますので、Playground
を使って実際に手を動かしながら行えると効率よく学習できるかなと思います。
Contents
Dictionary<Key, Value>型とは
Dictionary<Key, Value>型
は辞書
を表します。
辞書
というのは、データの集まりをまとめて格納するデータ構造であるコレクション
の1つで、キーと値のペアを持ちます。
Swift
で主要なコレクション
は配列 (Array)
、集合 (Set)
、辞書 (Dictionary)
の3つがあります。
Dictionary<Key, Value>型
のKey
とValue
の部分は、実際に使うときには具体的な型で置き換えて、Dictionary<String, Int>型
のようにします。
辞書の宣言方法
Dioctionary<Key, Value>型
は以下のようにキー
と値
を:
で分けて、[]
で囲みます。
let dictionay1: Dictionary<String, Int> = ["key1": 1, "key2": 2]
let dictionay2: Dictionary<String, String> = ["key1": "a", "key2": "b"]
上記の例では、Dictionary<String, Int>
やDictionary<String, String>
と記述しましたが、[String: Int]
や[String: String]
と書くこともできます。
実際に使うときは[String: Int]
や[String: String]
というように書くほうが一般的です。
このように、すでに定義されている構文をより簡単に読み書きできるように導入されている構文をシンタックスシュガー
といいます。
let dictionay1: [String: Int] = ["key1": 1, "key2": 2]
let dictionay2: [String: String] = ["key1": "a", "key2": "b"]
2種類の表現が同じ意味を表す表現というのをわかっていないと、見たときに混乱してしまうのでしっかり押さえておきましょう。
辞書のルール
辞書
はキー
と値
がペアになっていて、キー
をもとに値
にアクセスする形式なので、キー
は他のものと被ってはいけません。
let dictionary: [String: Int] = ["key": 1, "key": 2] //実行時エラー
値
に関しては、他のものと重複しても大丈夫です。
let dictionary: [String: Int] = ["key1": 1, "key2": 1]
キー
も値
も、異なる型を入れることはできません。
let dictionary1: [String: Int] = ["key": 1, 1: 1] //コンパイルエラー
let dictionary2: [String: Int] = ["key1": 1, "key2": "1"] //コンパイルエラー
型推論
辞書
の要素が推論可能な場合、型アノテーション
を省略することができます。
以下の例はキー
がString型
で、値はInt型
なので[String: Int]型
と推論されます。
let dictionay = ["key1": 1, "key2": 2] //[String: Int]型
型アノテーション
とはlet b: [String: Int]
の: [String: Int]
の部分で型を明示的にする際に使用します。
要素が空の辞書は[:]
と表します。
要素が空の場合には型アノテーション
を付けて、型を明示する必要があります。
let a = [:] //コンパイルエラー
let b: [String: Int] = [:]
キーと値に使える型
Dictionary<Key, Value>型
は定義を見てみると、
struct Dictionary<Key, Value> where Key: Hashable
となっています。
どういうことかというとKey
に関してはHashableプロトコル
に準拠したものに制限されます。
プロトコル
に関しては、後日別で記事にまとめるので、ここでは軽く触れるだけにします。
簡単にまとめると、Key
は一意でないといけないので、他とかぶっていないかを計算するためにハッシュ値
というものを用いる必要があるので、Key
はハッシュ値
を計算できるものでなければならないという成約があります。
String型
やInt型
はその条件を満たしているのでKey
として使用可能です。
他にも条件を満たしている型はありますが、実際にKey
としてよく使うのはその2つぐらいなので、それをおさえておけば問題ないと思います。
一方、Value
に関しては特に成約がないので、どんな型でも当てはめることができます。
[String: [Int]]型
や[String: [String: Int]]型
というようにすることもできます。
let a: [String: [Int]] = ["key": [1, 2, 3]]
let b: [String: [String: Int]] = ["key": ["key": 1]]
Dictionary<Key, Value>型の操作
ここからはDictionary<Key, Value>型
の基本的な操作についてまとめていきます。
値へのアクセス方法
Dictionary<Key, Value>型
の値にアクセスするには、以下のように[Key]
の形式でアクセスします。
let dictionary: [String: Int] = ["key1": 1, "key2": 2]
dictionary["key1"] //1 (Optional<Int>型)
dictionary["key2"] //2 (Optional<Int>型)
dictionary["key3"] //nil
[インデックス]
の部分をサブスクリプトといいます。
Dictionary<Key, Value>型
では存在しないキー
を指定したとしても、実行時エラーにはなりません。
そのかわりに、nil
を含む可能性があるので、取り出した値はオプショナル型
になります。
なので取り出した値を扱う場合はnil
かどうかの場合分けをする必要があります。
オプショナル型
に関してはこちらの記事で解説しています。
値の更新
辞書の要素の更新を行いたい場合は、以下のように更新したいキー
を指定して、=
で代入する形で書きます。
こちらは変数でないと実行できません。
var dictionary1: [String: Int] = ["key": 1]
dictionary1["key"] = 10
print(dictionary1) //["key": 10]
let dictionary2: [String: Int] = ["key": 1]
dictionary2["key"] = 10 //コンパイルエラー
値を追加
辞書
に要素を追加する場合は、値
の更新と同様に、追加したいキー
を指定して値
を=
で代入する形で書きます。
こちらも、元の辞書
を書き換える形になるものは変数でないと使えません。
var dictionary1: [String: Int] = ["key1": 1]
dictionary1["key2"] = 2
let dictionary2: [String: Int] = ["key1": 1]
dictionary2["key2"] = 2 //コンパイルエラー
値の削除
値
を削除するには、削除したいキー
を指定して、nil
を代入することで可能です。
var dictionary1: [String: Int] = ["key": 1]
dictionary1["key"] = nil
let dictionary2: [String: Int] = ["key": 1]
dictionary2["key"] = nil //コンパイルエラー
値の更新、追加、削除のまとめ
Dictionary<Key, Value>型
の値の更新、追加、削除のやり方を解説していきましたが、気づいた人もいるかも知れませんが、表記の仕方が全て同じになっています。
指定したキー
が存在していれば更新、存在していなければ追加、nil
を代入すれば削除となるのでしっかりおさえておきましょう。
- 指定した
キー
が存在していれば更新 - 指定した
キー
が存在していなければ追加 nil
を代入すれば削除
まとめ
今回は、Dictionary<Key, Value>型
に関してまとめていきました。
Dictionary<Key, Value>型
はSwift
の基本事項なのでしっかり押さえておきましょう。
Swift
の入門記事に関してはこちらにまとめていますので参考にしてみてください。