【Swift】ディクショナリ(辞書)の使い方。キーと値のペアを1つとしたデータの集まり。(Swift 2.1、XCode 7.2)
辞書を作る
ディクショナリ(辞書)とは、キーと値を1セットとした複数のデータを1つの変数で管理できる入れ物のことをいう。
「名前(キー)」は「山田(値)」、「年齢(キー)」は「32(値)」のように、キーを使って辞書から1つの値を得るイメージである。他の言語ではハッシュマップや連想配列などと呼ばれている。
辞書は以下のコードのように[キー:値,キー:値,キー:値,キー:値, …]で作る。キーと値の型を指定しなければ、型を混在して格納することができる。
配列と同じように、var(変数)で宣言した辞書はコードの中で要素の変更ができ、let(定数)で宣言した辞書は要素を変更することはできない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/* ** 辞書を作る */ //型を指定せずに辞書を作る var test1 = ["名前":"山田", "年齢":32, "出身":"茨城"] print(test1) //実行結果 //["名前": 山田, "年齢": 32, "出身": 茨城] //別の書き方 var test2:Dictionary = ["名前":"山田", "年齢":32, "出身":"茨城"] print(test2) //実行結果 //["名前": "山田", "年齢": 32, "出身": "茨城"] |
キーと値の型を指定した場合は辞書に格納する型を制限でき、指定した型以外のキーや値を格納しようとするとエラーが発生する。間違った使い方を防止するために、通常は型を指定して作ったほうがよさそうだ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/* ** 型を指定して辞書を作る */ //型を指定して辞書を作る var test3:[String:String] = ["名前":"山田", "年齢":"32", "出身":"茨城"] print(test3) //実行結果 //["名前": "山田", "年齢": "32", "出身": "茨城"] //別の書き方 var test4:Dictionary<String,String> = ["名前":"山田", "年齢":"32", "出身":"茨城"] print(test4) //実行結果 //["名前": "山田", "年齢": "32", "出身": "茨城"] //指定した型以外のキーを入れようとするとエラー var test5:Dictionary<String,String> = ["名前":"山田", 100:"健康"] //実行結果 //error: cannot convert value of type 'Int' to expected dictionary key type 'String' //指定した型以外の値を入れようとしてもエラー var test6:Dictionary<String,String> = ["名前":"山田", "年齢":35] //実行結果 //error: cannot convert value of type 'Int' to expected dictionary value type 'String' |
キーの型は制限し、値の型は自由にする場合は、以下のコードのようにAnyObjectを指定する。よく使うので覚えておこう。
1 2 3 4 5 6 7 8 9 10 11 |
/* ** 値の型は自由の辞書を作る */ //型を指定して辞書を作る var test7:[String:AnyObject] = ["名前":"山田", "年齢":32, "`身長":170.5] print(test7) //実行結果 //["名前": 山田, "年齢": 32, "`身長": 170.5] |
空の辞書を作るには以下のコードのようにする。最初は空の辞書を作成し、処理の中で要素を追加する使い方ができる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* ** 空の辞書を作る */ //型を指定して空の辞書を作る var test8:[String:Int] = [:] //これが一番しっくりくる var test9 = [String:Int]() //別の書き方 var test10 = Dictionary<String,Int>() //別の書き方 //型を指定しないで空の辞書を作る var test11 = [:] |
辞書の要素を取得する
辞書の要素を取得するには、以下のコードのように辞書名[“キー"]で取得する。取得した値はオプショナル型なので、処理の中で使う場合はアンラップする必要がある。(オプショナル型について詳しくは⇒「記事」)
1 2 3 4 5 6 7 |
/* ** 辞書の要素を取得する */ var zisho:[String:String] = ["名前": "山田", "年齢": "32", "出身": "栃木"] print(zisho["名前"]! + "さん") |
配列や辞書などのコレクション型変数の要素を取得するときは、要素を1つずつ取り出しながらすべての要素を処理することが多い。その場合はfor-in文を用いて以下のコードのように取得する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
/* ** 辞書の要素を取得する例 */ //辞書のすべての要素を1つずつ取得する。 var zisho:[String:String] = ["名前": "山田", "年齢": "32", "出身": "栃木"] for (testkey,testvalue) in zisho { print("キーは\(testkey)、値は\(testvalue)") } //実行結果 //キーは名前、値は山田 //キーは年齢、値は32 //キーは出身、値は栃木 //辞書のすべてのキーを1つずつ取得する for test in zisho.keys { print("キーは\(test)") } //実行結果 //キーは名前 //キーは年齢 //キーは出身 //辞書のすべての値を1つずつ取得する例 for test in zisho.values { print("値は\(test)") } //実行結果 //値は山田 //値は32 //値は栃木 |
その他、辞書の情報を知るプロパティやメソッドには以下のようなものがある。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
var zisho:[String:String] = ["名前": "山田", "年齢": "32", "出身": "栃木"] zisho.removeValueForKey("出身") //辞書が空かをチェック print(zisho.isEmpty) //実行結果 true //辞書の要素数を取得 print(zisho.count) //実行結果 2 //キーと値のセットで辞書を検索する print(zisho.contains{ $0.0 == "名前" && $0.1 == "山田" }) //実行結果 true //キーで辞書を検索する print(zisho.keys.contains("年齢")) //実行結果 true //値で辞書を検索する print(zisho.values.contains("青森")) //実行結果 false //配列の中身を表示 print(zisho.description) print(zisho.debugDescription) //実行結果 ["名前": "山田", "年齢": "32"] |
辞書の要素を操作する
辞書に要素を追加するには、以下のコードのようにする。指定したキーが辞書に登録されていなければ新規追加、すでに登録されていれば更新になる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* ** updateValueメソッドを用いて辞書に要素を追加する */ var test12:[String:String] = ["名前":"山田"] test12.updateValue("32", forKey: "年齢") test12.updateValue("茨城", forKey: "出身") test12.updateValue("栃木", forKey: "出身") print(test12) //実行結果 //["名前": "山田", "年齢": "32", "出身": "栃木"] |
updateVallueメソッドは更新前の値が戻ってくるので、更新されたのか、新規追加されたのかを戻り値から判別することができる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* ** updateValueメソッドは更新前の値が返ってくる */ var test12:[String:String] = ["名前": "山田", "年齢": "32", "出身": "栃木"] let old = test12.updateValue("55", forKey: "年齢") if old == nil { print("新規追加") } else { print("更新前 \(old!)") } print(test12) //実行結果 //更新前 32 //["名前": "山田", "年齢": "55", "出身": "栃木"] |
以下のコードのように、辞書に含まれる要素にアクセスするような書き方で追加することもできる。updateValueメソッドだとキーと値の書き順が逆になってて混乱するのでこの方が書きやすい。
1 2 3 4 5 6 7 8 9 10 11 12 |
/* ** 辞書に要素を追加する */ var test12:[String:String] = ["名前":"山田"] test12["年齢"] = "32" test12["出身"] = "茨城" print(test12) //実行結果 //["名前": "山田", "年齢": "32", "出身": "茨城"] |
辞書から要素を削除するには、以下のコードのようにする。updateVallueメソッドと同様に、削除前のデータが戻ってくるので、データが削除されたかどうかを判別することができる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
/* ** remove系メソッドを使って辞書から要素を削除する */ //removeValueForKeyメソッドで特定の要素を削除 var test14:[String:String] = ["名前": "山田", "年齢": "32", "出身": "茨城"] let old = test14.removeValueForKey("年齢") if old == nil { print("削除データ無し") } else { print("削除実施 \(old!)") } print(test14) //実行結果 //削除実施 32 //["名前": "山田", "出身": "茨城"] //removeAllメソッドですべての要素を削除 var test15:[String:String] = ["名前": "山田", "年齢": "32", "出身": "茨城"] test15.removeAll() print(test15) //実行結果 //[:] |
これに関しても、辞書に含まれる要素にアクセスするような書き方で削除できる。値にnilを設定すると辞書から要素が削除される。
1 2 3 4 5 6 7 8 9 10 11 12 |
/* ** 辞書から要素を削除する */ var test13:[String:String] = ["名前": "山田", "年齢": "32", "出身": "茨城"] test13["年齢"] = nil test13["出身"] = nil print(test13) //実行結果 //["名前": "山田"] |
ちなみに、以下のコードのように辞書の値をオプショナル型に指定して、値にnilを設定した場合は要素は削除されないのかと思いきや、通常どおり削除された。
1 2 3 4 5 6 7 8 9 10 11 12 |
/* * オプショナル型の値でもnilを設定すれば削除できる。 */ var test13:[String:String?] = ["名前": "山田", "年齢": "32", "出身": "茨城"] test13["年齢"] = nil test13["出身"] = nil print(test13) //実行結果 //["名前": Optional("山田")] |