Swift字典
字典
字典是一種存儲多個相同類型的值的容器。每個值(value)都關聯唯一的鍵(key),鍵作爲字典中的這個值數據的標識符。和數組中的數據項不同,字典中的數據項並沒有具體順序。我們在需要通過標識符(鍵)訪問數據的時候使用字典,這種方法很大程度上和我們在現實世界中使用字典查字義的方法一樣。
Swift 的字典使用時需要具體規定可以存儲鍵和值類型。不同於 Objective-C 的NSDictionary
和NSMutableDictionary
類可以使用任何類型的對象來作鍵和值並且不提供任何關於這些對象的本質信息。在 Swift 中,在某個特定字典中可以存儲的鍵和值必須提前定義清楚,方法是通過顯性類型標註或者類型推斷。
Swift 的字典使用Dictionary<KeyType, ValueType>
定義,其中KeyType
是字典中鍵的數據類型,ValueType
是字典中對應於這些鍵所存儲值的數據類型。
KeyType
的唯一限制就是可哈希的,這樣可以保證它是獨一無二的,所有的 Swift 基本類型(例如String
,Int
,Double
和Bool
)都是默認可哈希的,並且所有這些類型都可以在字典中當做鍵使用。未關聯值的枚舉成員(參見枚舉)也是默認可哈希的。
字典字面量
我們可以使用字典字面量來構造字典,它們和我們剛纔介紹過的數組字面量擁有相似語法。一個字典字面量是一個定義擁有一個或者多個鍵值對的字典集合的簡單語句。
一個鍵值對是一個key
和一個value
的結合體。在字典字面量中,每一個鍵值對的鍵和值都由冒號分割。這些鍵值對構成一個列表,其中這些鍵值對由方括號包含並且由逗號分割:
[key 1: value 1, key 2: value 2, key 3: value 3]
下面的例子創建了一個存儲國際機場名稱的字典。在這個字典中鍵是三個字母的國際航空運輸相關代碼,值是機場名稱:
var airports: Dictionary<String, String> = ["TYO": "Tokyo", "DUB": "Dublin"]
airports
字典被定義爲一種Dictionary<String, String>
,它意味着這個字典的鍵和值都是String
類型。
注意:
airports
字典被聲明爲變量(用var
關鍵字)而不是常量(let
關鍵字)因爲後來更多的機場信息會被添加到這個示例字典中。
airports
字典使用字典字面量初始化,包含兩個鍵值對。第一對的鍵是TYO
,值是Tokyo
。第二對的鍵是DUB
,值是Dublin
。
這個字典語句包含了兩個String: String
類型的鍵值對。它們對應airports
變量聲明的類型(一個只有String
鍵和String
值的字典)所以這個字典字面量是構造兩個初始數據項的airport
字典。
和數組一樣,如果我們使用字面量構造字典就不用把類型定義清楚。airports
的也可以用這種方法簡短定義:
var airports = ["TYO": "Tokyo", "DUB": "Dublin"]
因爲這個語句中所有的鍵和值都分別是相同的數據類型,Swift 可以推斷出Dictionary<String, String>
是airports
字典的正確類型。
讀取和修改字典
我們可以通過字典的方法和屬性來讀取和修改字典,或者使用下標語法。和數組一樣,我們可以通過字典的只讀屬性count
來獲取某個字典的數據項數量:
println("The dictionary of airports contains \(airports.count) items.")
// 打印 "The dictionary of airports contains 2 items."(這個字典有兩個數據項)
我們也可以在字典中使用下標語法來添加新的數據項。可以使用一個合適類型的 key 作爲下標索引,並且分配新的合適類型的值:
airports["LHR"] = "London"
// airports 字典現在有三個數據項
我們也可以使用下標語法來改變特定鍵對應的值:
airports["LHR"] = "London Heathrow"
// "LHR"對應的值 被改爲 "London Heathrow
作爲另一種下標方法,字典的updateValue(forKey:)
方法可以設置或者更新特定鍵對應的值。就像上面所示的示例,updateValue(forKey:)
方法在這個鍵不存在對應值的時候設置值或者在存在時更新已存在的值。和上面的下標方法不一樣,這個方法返回更新值之前的原值。這樣方便我們檢查更新是否成功。
updateValue(forKey:)
函數會返回包含一個字典值類型的可選值。舉例來說:對於存儲String
值的字典,這個函數會返回一個String?
或者「可選 String
」類型的值。如果值存在,則這個可選值值等於被替換的值,否則將會是nil
。
if let oldValue = airports.updateValue("Dublin Internation", forKey: "DUB") {
println("The old value for DUB was \(oldValue).")
}
// 輸出 "The old value for DUB was Dublin."(DUB原值是dublin)
我們也可以使用下標語法來在字典中檢索特定鍵對應的值。由於使用一個沒有值的鍵這種情況是有可能發生的,可選類型返回這個鍵存在的相關值,否則就返回nil
:
if let airportName = airports["DUB"] {
println("The name of the airport is \(airportName).")
} else {
println("That airport is not in the airports dictionary.")
}
// 打印 "The name of the airport is Dublin Internation."(機場的名字是都柏林國際)
我們還可以使用下標語法來通過給某個鍵的對應值賦值爲nil
來從字典裏移除一個鍵值對:
airports["APL"] = "Apple Internation"
// "Apple Internation"不是真的 APL機場, 刪除它
airports["APL"] = nil
// APL現在被移除了
另外,removeValueForKey
方法也可以用來在字典中移除鍵值對。這個方法在鍵值對存在的情況下會移除該鍵值對並且返回被移除的value或者在沒有值的情況下返回nil
:
if let removedValue = airports.removeValueForKey("DUB") {
println("The removed airport's name is \(removedValue).")
} else {
println("The airports dictionary does not contain a value for DUB.")
}
// prints "The removed airport's name is Dublin International."
字典遍歷
我們可以使用for-in
循環來遍歷某個字典中的鍵值對。每一個字典中的數據項都由(key, value)
元組形式返回,並且我們可以使用臨時常量或者變量來分解這些元組:
for (airportCode, airportName) in airports {
println("\(airportCode): \(airportName)")
}
// TYO: Tokyo
// LHR: London Heathrow
for-in
循環請參見For 循環。
我們也可以通過訪問它的keys
或者values
屬性(都是可遍歷集合)檢索一個字典的鍵或者值:
for airportCode in airports.keys {
println("Airport code: \(airportCode)")
}
// Airport code: TYO
// Airport code: LHR
for airportName in airports.values {
println("Airport name: \(airportName)")
}
// Airport name: Tokyo
// Airport name: London Heathrow
如果我們只是需要使用某個字典的鍵集合或者值集合來作爲某個接受Array
實例 API 的參數,可以直接使用keys
或者values
屬性直接構造一個新數組:
let airportCodes = Array(airports.keys)
// airportCodes is ["TYO", "LHR"]
let airportNames = Array(airports.values)
// airportNames is ["Tokyo", "London Heathrow"]
注意:
Swift 的字典類型是無序集合類型。其中字典鍵,值,鍵值對在遍歷的時候會重新排列,而且其中順序是不固定的。
創建一個空字典
我們可以像數組一樣使用構造語法創建一個空字典:
var namesOfIntegers = Dictionary<Int, String>()
// namesOfIntegers 是一個空的 Dictionary<Int, String>
這個例子創建了一個Int, String
類型的空字典來儲存英語對整數的命名。它的鍵是Int
型,值是String
型。
如果上下文已經提供了信息類型,我們可以使用空字典字面量來創建一個空字典,記作[:]
(中括號中放一個冒號):
namesOfIntegers[16] = "sixteen"
// namesOfIntegers 現在包含一個鍵值對
namesOfIntegers = [:]
// namesOfIntegers 又成爲了一個 Int, String類型的空字典
注意:
在後臺,Swift 的數組和字典都是由泛型集合來實現的,想了解更多泛型和集合信息請參見泛型。