位置:首頁 > 高級語言 > Swift教學 > Swift字典

Swift字典

字典

字典是一種存儲多個相同類型的值的容器。每個值(value)都關聯唯一的鍵(key),鍵作為字典中的這個值數據的標識符。和數組中的數據項不同,字典中的數據項並冇有具體順序。我們在需要通過標識符(鍵)訪問數據的時候使用字典,這種方法很大程度上和我們在現實世界中使用字典查字義的方法一樣。

Swift 的字典使用時需要具體規定可以存儲鍵和值類型。不同於 Objective-C 的NSDictionaryNSMutableDictionary 類可以使用任何類型的對象來作鍵和值並且不提供任何關於這些對象的本質信息。在 Swift 中,在某個特定字典中可以存儲的鍵和值必須提前定義清楚,方法是通過顯性類型標注或者類型推斷。

Swift 的字典使用Dictionary<KeyType, ValueType>定義,其中KeyType是字典中鍵的數據類型,ValueType是字典中對應於這些鍵所存儲值的數據類型。

KeyType的唯一限製就是可哈希的,這樣可以保證它是獨一無二的,所有的 Swift 基本類型(例如StringIntDoubleBool)都是默認可哈希的,並且所有這些類型都可以在字典中當做鍵使用。未關聯值的枚舉成員(參見枚舉)也是默認可哈希的。

字典字麵量

我們可以使用字典字麵量來構造字典,它們和我們剛才介紹過的數組字麵量擁有相似語法。一個字典字麵量是一個定義擁有一個或者多個鍵值對的字典集合的簡單語句。

一個鍵值對是一個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 的數組和字典都是由泛型集合來實現的,想了解更多泛型和集合信息請參見泛型