Swift入門(六)——字典(Dictionary)

字典的定義

和上一篇文章講到的數組類似,字典也是用來存放相同數據類型的元素的數據結構。不過字典是通過鍵(Key)來查找特定的值(Value),字典中存放的每一個數據項(item)都是這樣的一個鍵值對。

哈希化

每一個鍵值對的值,沒有特殊要求,但是隻有可以哈希化的類型的變量,纔可以作爲鍵值對的鍵。可以哈希化是指,該類型的變量,必須提供一個可以計算出自身哈希值的方法。哈希值不相同的變量,自身一定也不相同,反之則不一定成立。

在判斷a == b的時候,其實會轉化爲a.hashValue == b.hashValue。Swift中所有的基礎類型(String,Int,Double,Bool等)都是可哈希化的類型,沒有關聯值的枚舉成員值也可以哈希化。自定義類型滿足協議Hashable,也可以哈希化。

創建字典

類比於數組的創建,字典的類型也有兩種寫法。這裏就不詳細介紹了,不明白的讀者可以閱讀上一篇文章中,介紹數組的創建的部分。直接給出代碼:

var dictionary1: Dictionary<String,Int> = ["key1": 1]
var dictionary2: [String: Int] = ["key2": 2"key3": 3]
println("dictionary1 = \(dictionary1)")
println("dictionary2 = \(dictionary2)")

字典的增刪改查

字典長度

完全類比數組長度的計算,字典長度也可以通過字典的count屬性獲得。

var dictionary1: Dictionary<String,Int> = ["key1": 1]
println("dictionary1 = \(dictionary1.count)")

判斷字典爲空

同樣的,可以使用字典的isEmpty屬性判斷字典是否爲空。

var dictionary1: Dictionary<String,Int> = ["key1": 1]
if !dictionary1.isEmpty{
    println("Dictionary is not empty")
}

增加字典元素

與數組調用append方法不同的是,字典可以通過附屬腳本的語法增加長度。具體使用方法爲:dictionaryName[newKey] = newValue。舉例如下:

var dictionary1: Dictionary<String,Int> = ["key1": 1]
dictionary1["key2"] = 2
println("dictionary1 = \(dictionary1)")

輸出結果:

dictionary1 = [key1: 1, key2: 2]

與數組不同的是,無法通過字典切片來添加字典元素。

訪問字典元素

字典中存儲的數據只能通過鍵來獲取。方法也比較簡單:

var dictionary1: Dictionary<String,Int> = ["key1": 1]
var value = dictionary1["key1"]  // 獲取value
println("value = \(value!)") 
dictionary1["key1"] = 2  // 修改value
println("dictionary1 = \(dictionary1)")

運行結果:

value = 1
dictionary1 = [key1: 2]

需要注意的是,由於鍵所對應的值並不一定存在,所以使用附屬腳本的語法獲得的值,是一個可選類型。需要解封后使用,具體使用方法可以在第四章找到詳細說明,這裏爲了節省(tou)篇幅(lan),我使用了了錯誤的,或者說是不嚴謹的解封方式。

除此之外可以看到,通過附屬腳本,不僅可以獲取字典中的值,還可以直接修改它們。當然,與數組類似地,也可以使用updateValue(forKey:)方法修改字典中的值。

var dictionary1: Dictionary<String,Int> = ["key1": 1]
dictionary1.updateValue(2, forKey: "key1")
dictionary1.updateValue(2, forKey: "key2")
println("dictionary1 = \(dictionary1)")

即使鍵不存在也沒關係,Swift會自動幫我們創建一條新的鍵值對。

刪除字典元素

使用附屬腳本也可以刪除字典中的元素。只要把值置爲nil即可,但是updateValue(forKey:)方法中的value參數不可以爲nil。

var dictionary1: Dictionary<String,Int> = ["key1": 1]
dictionary1.updateValue(2, forKey: "key2")
println("dictionary1 = \(dictionary1)")

dictionary1["key2"] = nil
//dictionary1.updateValue(nil, forKey: "key1") // 語法錯誤,參數不能爲nil
println("dictionary1 = \(dictionary1)")

運行結果:

dictionary1 = [key1: 1, key2: 2]
dictionary1 = [key1: 1]

removeAll方法可以移除字典中所有的數據。

var dictionary1: Dictionary<String,Int> = ["key1": 1]
dictionary1.removeAll(keepCapacity: true)

//還有最簡單的寫法
dictionary1 = [:]

不管keepCapacity是否爲true,執行完這一行代碼後的dictionary1,isEmpty = true,count = 0。

keepCapacity: If true, is a non-binding request to avoid releasing storage, which can be a useful optimization when x is going to be grown again.

如果keepCapacity被設置爲true,那麼分配給字典的空間不會被釋放,如果字典還會再次添加內容,這樣做是一種性能上的優化。但即使這樣,字典的count屬性依然爲0。

字典的刪除還有一種方法,即使用removeAtIndex方法。其中的參數應該是一個DictionaryIndex類型的對象,需要通過indexForKey方法獲取到一個可選類型,再解封。注意如果可選類型裏的值爲nil,不能調用removeAtIndex方法!否則會導致運行時錯誤。爲了節省(tou)篇幅(lan),這裏就不給出強制類型解封的代碼了。

var dictionary1: Dictionary<String,Int> = ["key1": 1]
dictionary1.removeAtIndex(dictionary1.indexForKey("key1")!)
println("dictionary1 = \(dictionary1)")

由於這種方法比較麻煩,難度也較大,所以不推薦使用。

遍歷字典

可以通過for in循環遍歷字典,不僅可以遍歷字典的鍵值對,還可以單獨歷字典的鍵或值。

var dictionary1: Dictionary<String,Int> = ["key1": 1,"key2": 2]
for (keyName,valueName) in dictionary1{
    println("keyName = \(keyName) valueName = \(valueName)")
}

如果想要單獨訪問鍵,只要把in後面的dictionary1改爲dictionary1.keys即可。

字典的初始化

字典的初始化方法與數組類似,不過只能使用標準的語法進行初始化,字典沒有特殊的構造器。

//這兩種寫法都可以創建一個空的字典
var dic1 = [String,Int]()
var dic2 = Dictionary<String,Int>()

總結

由於字典是無序的,所以總體上的操作要比數組簡單一些。與OC中的NSDictionary相比,Swift中的字典更加容易修改,語法簡單,不過各種瑣碎的細節也會比較多,不像OC中可以固定使用那麼幾種語法。

無論讀者在看到本文時,是否已經瞭解過Swift中的數組,都建議將數組和字典結合起來學習,比較他們的異同。

附錄

查看完整專欄——《Swift輕鬆入門》

【Swift入門(一)——基本語法】
【Swift入門(二)——字符與字符串】
【Swift入門(三)——元組(Tuple)】
【Swift入門(四)——可選類型(Optionals)與斷言(Assert)】
【Swift入門(五)——數組(Array)】
【Swift入門(六)——字典(Dictionary)】
【Swift入門(七)——結構體(Struct)】
【Swift入門(八)——功能強大的求餘運算符】
【Swift入門(九)——String與Int、Double、Float等數字相互轉換】
【Swift入門(十)——循環引用、弱引用和無主引用】
【Swift入門(十一)——類型轉換與is、as操作】
【Swift入門(十二)——利用Extension添加逆序輸出字符串方法】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章