ディクショナリ

ディクショナリは、文字列や数値をキーにして値を格納したり参照できる型です。

宣言

ディクショナリは次のように、「[」と「]」の間に「:」(コロン)で区切ったキーと値のペアを「,」(カンマ)区切りで記述して初期化できます。


let party: Dictionary<String, String> = ["ルフィ": "船長", "ゾロ": "剣士", "ナミ":"航海士"]
if let job = party["ゾロ"] {
    print(job)      // 剣士
}
let items: Dictionary<String, Int> = ["りんご": 100, "みかん": 300, "バナナ": 150]
if let price = items["みかん"] {
    print(price)    // 300
}

次のように、「[」と「]」の間に「:」(コロン)で区切ってキーと値の型を指定することもできます。


let party: [String: String] = ["ルフィ": "船長", "ゾロ": "剣士", "ナミ":"航海士"]
let items: [String: Int] = ["りんご": 100, "みかん": 300, "バナナ": 150]

初期値を与える場合は要素から型が推測されるので型の明示は不要です。


let party = ["ルフィ": "船長", "ゾロ": "剣士", "ナミ": "航海士"]
let items = ["りんご": 100, "みかん": 300, "バナナ": 150]

空のディクショナリは次の様に宣言できます。


// キーがString型、値がString型のディクショナリ
var party: Dictionary<String, String> = [:]
// 又は
var party: [String: String] = [:]
// 又は
var party = Dictionary<String, String>()
// 又は
var party = [String: String]()

// キーがString型、値がInt型のディクショナリ
var items: Dictionary<String, Int> = [:] 
// 又は
var items: [String: Int] = [:]
// 又は
var items = Dictionary<String, Int>()
// 又は
var items = [String: Int]()

ディクショナリのキーには、Hashableプロトコルに適合する型であればなんでも使用することができます。IntやFloat, Double, StringはHashableプロトコルに適合しています。ArrayやDictionaryもHashableプロトコルに適合しているので、これらの型をキーとして使用することもできます。但し、タプルはHashableプロトコルに適合していません。
独自の型をHashableプロトコルに適合させるには、Int型を返すhashValueプロパティと、同一値かどうかを返す==演算子を実装する必要があります。

要素の変更、追加

値を修正したり追加するには、該当するキーの値を代入します。


var party = ["ルフィ": "船長", "ゾロ": "剣士", "ナミ": "航海士"]
party["サンジ"] = "コック"    // ["ルフィ": "船長", "ゾロ": "剣士", "ナミ": "航海士", "サンジ": "コック"]

var items = ["りんご": 100, "バナナ": 150, "みかん": 300]
items["バナナ"] = 200  // ["りんご": 100, "バナナ": 200, "みかん": 300]
items["いちご"] = 400  // ["いちご": 400, "バナナ": 200, "りんご": 100, "みかん": 300]

ディクショナリを定数として宣言した場合は、値の変更や追加はできません。


let items = ["りんご": 100, "みかん": 300, "バナナ": 150]
items["バナナ"] = 200  // エラー
items["いちご"] = 400  // エラー

updateValueメソッドを使うと、値を更新し、更新前の値を取り出すことができます。


var items = ["りんご": 100, "みかん": 300, "バナナ": 150]
let oldPrice = items.updateValue(200, forKey:"みかん") // ["りんご": 100, "みかん": 200, "バナナ": 150]
print(oldPrice)   // 300

ディクショナリの要素数は、配列と同様、countプロパティで取得することができます。


let party: Dictionary<String, String> = ["ルフィ": "船長", "ゾロ": "剣士", "ナミ":"航海士"]
print("パーティの人数は、\(party.count)人") // パーティの人数は、3人

要素の削除

ディクショナリから要素を削除するには、該当するキーの値にnilを代入します。


var party = ["ルフィ": "船長", "ゾロ": "剣士", "ウソップ": "狙撃手", "ナミ":"航海士"]
print("パーティの人数は、\(party.count)人") // パーティの人数は、4人
party["ウソップ"] = nil // ["ルフィ": "船長", "ゾロ": "剣士", "ナミ":"航海士"]
print("パーティの人数は、\(party.count)人") // パーティの人数は、3人

removeValueForKeyメソッドを使うと、要素を削除し、削除前の値を取り出すことができます。


var party = ["ルフィ": "船長", "ゾロ": "剣士", "ウソップ": "狙撃手", "ナミ":"航海士"]
if let oldValue = party.removeValueForKey("ウソップ") {
    print(oldValue)   // 狙撃手
}

既に型情報をもっているディクショナリは、[:]を代入することで初期化できます。


var items = ["りんご": 100, "みかん": 300, "バナナ": 150]
items["ぶどう"] = 500
:
items = [:]

イティレーション

ディクショナリは次のようにfor文を使って繰り返し処理ができます。


let items = ["りんご": 100, "みかん": 300, "バナナ": 150]
for (name, price) in items {
    print("\(name): \(price)円")
}
/*
りんご: 100円
バナナ: 150円
みかん: 300円
*/

次の様にしてキーのみ、又は値のみを繰り返し処理することもできます。


let items = ["りんご": 100, "みかん": 300, "バナナ": 150]

// キーを出力
for name in items.keys {
    print(name)
}
/*
りんご
バナナ
みかん
*/

// 値を出力
for price in items.values {
    print("\(price)円")
}
/*
100円
150円
300円
*/

ディクショナリの要素の順番は決められていません。for文で処理する時に、宣言した順番で処理されるとは限りません。

ディクショナリのコピー

ディクショナリを別の変数に代入すると、ディクショナリ全体がコピーされます。そのため、一方のディクショナリの値を変えても、もう一方のディクショナリの中身に影響はありません。


var items = ["りんご": 100, "みかん": 300, "バナナ": 150]
var items2 = items
items2["みかん"] = 350
print(items)      // ["りんご": 100, "みかん": 300, "バナナ": 150]
print(items2)     // ["りんご": 100, "みかん": 350, "バナナ": 150]