Swift 語言提供Arrays、Sets和Dictionaries三種基本的集合類型用來存儲集合數據。數組(Arrays)是有序數據的集。集合(Sets)是無序無重復數據的集。字典(Dictionaries)是無序的鍵值對的集。Swift 語言中的Arrays、Sets和Dictionaries中存儲的數據值類型必須明確。這意味著我們不能把不正確的數據類型插入其中。同時這也說明我們完全可以對取回值的類型非常自信。
集合的可變性
如果創建一個Arrays、Sets或Dictionaries并且把它分配成一個變量,這個集合將會是可變的。這意味著我們可以在創建之后添加更多或移除已存在的數據項,或者改變集合中的數據項。如果我們把Arrays、Sets或Dictionaries分配成常量,那么它就是不可變的,它的大小和內容都不能被改變。
數組(Arrays)
寫 Swift 數組應該遵循像Array<Element>這樣的形式,其中Element是這個數組中唯一允許存在的數據類型。我們也可以使用像[Element]這樣的簡單語法。
創建數組
可以使用構造語法來創建一個由特定數據類型構成的空數組
var someInts = [Int]()
print("someInts is of type [Int] with \(someInts.count) items.")
// 打印 "someInts is of type [Int] with 0 items."
someInts.append(3)
// someInts 現在包含一個 Int 值
someInts = []
// someInts 現在是空數組,但是仍然是 [Int] 類型的。
Swift 中的Array類型還提供一個可以創建特定大小并且所有數據都被默認的構造方法。我們可以把準備加入新數組的數據項數量(count)和適當類型的初始值(repeating)傳入數組構造函數
var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles 是一種 [Double] 數組,等價于 [0.0, 0.0, 0.0]
可以使用加法操作符(+)來組合兩種已存在的相同類型數組。新數組的數據類型會被從兩個數組的數據類型中推斷出來
var anotherThreeDoubles = Array(repeating: 2.5, count: 3)
// anotherThreeDoubles 被推斷為 [Double],等價于 [2.5, 2.5, 2.5]
var sixDoubles = threeDoubles + anotherThreeDoubles
// sixDoubles 被推斷為 [Double],等價于 [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
可以使用數組字面量來進行數組構造,這是一種用一個或者多個數值構造數組的簡單方法。數組字面量是一系列由逗號分割并由方括號包含的數值 [value 1, value 2, value 3]
var shoppingList = ["Eggs", "Milk"]
// shoppingList 已經被構造并且擁有兩個初始項。
訪問和修改數組
可以使用數組的只讀屬性count來獲取數組中的數據項數量
使用布爾屬性isEmpty作為一個縮寫形式去檢查count屬性是否為0
也可以使用append(_:)方法在數組后面添加新的數據項
使用下標語法來獲取數組中的數據項,把我們需要的數據項的索引值放在直接放在數組名稱的方括號中
可以用下標來改變某個已有索引值對應的數據值
還可以利用下標來一次改變一系列數據值,即使新數據和原有數據的數量是不一樣的。下面的例子把"Chocolate Spread","Cheese",和"Butter"替換為"Bananas"和"Apples"
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList 現在有6項
調用數組的insert(_:at:)方法來在某個具體索引值之前添加數據項
使用remove(at:)方法來移除數組中的某一項。這個方法把數組在特定索引值中存儲的數據項移除并且返回這個被移除的數據項(我們不需要的時候就可以無視它)
如果我們只想把數組中的最后一項移除,可以使用removeLast()方法而不是remove(at:)方法來避免我們需要獲取數組的count屬性。就像后者一樣,前者也會返回被移除的數據項
數組的遍歷
可以使用for-in循環來遍歷所有數組中的數據項
如果我們同時需要每個數據項的值和索引值,可以使用enumerated()方法來進行數組遍歷。enumerated()返回一個由每一個數據項索引值和數據值組成的元組。我們可以把這個元組分解成臨時常量或者變量來進行遍歷
for (index, value) in shoppingList.enumerated() {
? ? print("Item \(String(index + 1)): \(value)")
}
集合(Sets)
Swift 中的Set類型被寫為Set,這里的Element表示Set中允許存儲的類型,和數組不同的是,集合沒有等價的簡化形式。
創建集合
可以通過構造器語法創建一個特定類型的空集合
var letters = Set()
print("letters is of type Setwith \(letters.count) items.")
// 打印 "letters is of type Setwith 0 items."
letters.insert("a")
// letters 現在含有1個 Character 類型的值
letters = []
// letters 現在是一個空的 Set, 但是它依然是 Set類型
可以使用數組字面量來構造集合,并且可以使用簡化形式寫一個或者多個值作為集合元素
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
// favoriteGenres 被構造成含有三個初始值的集合
一個Set類型不能從數組字面量中被單獨推斷出來,因此Set類型必須顯式聲明。然而,由于 Swift 的類型推斷功能,如果你想使用一個數組字面量構造一個Set并且該數組字面量中的所有元素類型相同,那么你無須寫出Set的具體類型。favoriteGenres的構造形式可以采用簡化的方式代替
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
訪問和修改集合
可以使用其只讀屬性count找出一個Set中元素的數量
使用布爾屬性isEmpty作為一個縮寫形式去檢查count屬性是否為0
通過調用Set的insert(_:)方法來添加一個新元素
通過調用Set的remove(_:)方法去刪除一個元素,如果該值是該Set的一個元素則刪除該元素并且返回被刪除的元素值,否則如果該Set不包含該值,則返回nil。另外,Set中的所有元素可以通過它的removeAll()方法刪除
使用contains(_:)方法去檢查Set中是否包含一個特定的值
集合的遍歷
可以在一個for-in循環中遍歷一個Set中的所有值
Swift 的Set類型沒有確定的順序,為了按照特定順序來遍歷一個Set中的值可以使用sorted()方法,它將返回一個有序數組,這個數組的元素排列順序由操作符'<'對元素進行比較的結果來確定
for genre in favoriteGenres.sorted() {
? ? print("\(genre)")
}
// prints "Classical"
// prints "Hip hop"
// prints "Jazz
集合操作
集合成員關系和相等
使用“是否相等”運算符(==)來判斷兩個集合是否包含全部相同的值。
使用isSubset(of:)方法來判斷一個集合中的值是否也被包含在另外一個集合中。
使用isSuperset(of:)方法來判斷一個集合中包含另一個集合中所有的值。
使用isStrictSubset(of:)或者isStrictSuperset(of:)方法來判斷一個集合是否是另外一個集合的子集合或者父集合并且兩個集合并不相等。
使用isDisjoint(with:)方法來判斷兩個集合是否不含有相同的值(是否沒有交集)。
字典(Dictionaries)
Swift 的字典使用Dictionary定義,其中Key是字典中鍵的數據類型,Value是字典中對應于這些鍵所存儲值的數據類型。我們也可以用[Key: Value]這樣簡化的形式去創建一個字典類型。
創建字典
可以像數組一樣使用構造語法創建一個擁有確定類型的空字典
var namesOfIntegers = [Int: String]()
// namesOfIntegers 是一個空的 [Int: String] 字典
namesOfIntegers[16] = "sixteen"
// namesOfIntegers 現在包含一個鍵值對
namesOfIntegers = [:]
// namesOfIntegers 又成為了一個 [Int: String] 類型的空字典
可以使用字典字面量來構造字典,這和我們剛才介紹過的數組字面量擁有相似語法。字典字面量是一種將一個或多個鍵值對寫作Dictionary集合的快捷途徑。
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
訪問和修改字典
通過字典的只讀屬性count來獲取某個字典的數據項數量
使用布爾屬性isEmpty作為一個縮寫形式去檢查count屬性是否為0
可以在字典中使用下標語法來添加新的數據項。可以使用一個恰當類型的鍵作為下標索引,并且分配恰當類型的新值
也可以使用下標語法來改變特定鍵對應的值
字典的updateValue(_:forKey:)方法可以設置或者更新特定鍵對應的值,在這個鍵不存在對應值的時候會設置新值或者在存在時更新已存在的值,返回更新值之前的原值
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
? ? print("The old value for DUB was \(oldValue).")
}
// 輸出 "The old value for DUB was Dublin."
可以使用下標語法來在字典中檢索特定鍵對應的值。因為有可能請求的鍵沒有對應的值存在,字典的下標訪問會返回對應值的類型的可選值。如果這個字典包含請求鍵所對應的值,下標會返回一個包含這個存在值的可選值,否則將返回nil
if let airportName = airports["DUB"] {
? ? print("The name of the airport is \(airportName).")
} else {
? ? print("That airport is not in the airports dictionary.")
}
// 打印 "The name of the airport is Dublin Airport."
可以使用下標語法來通過給某個鍵的對應值賦值為nil來從字典里移除一個鍵值對
airports["APL"] = "Apple Internation"
// "Apple Internation" 不是真的 APL 機場, 刪除它
airports["APL"] = nil
// APL 現在被移除了
removeValue(forKey:)方法也可以用來在字典中移除鍵值對。這個方法在鍵值對存在的情況下會移除該鍵值對并且返回被移除的值或者在沒有值的情況下返回nil
if let removedValue = airports. removeValue(forKey: "DUB") {
? ? print("The removed airport's name is \(removedValue).")
} else {
? ? print("The airports dictionary does not contain a value for DUB.")
}
// prints "The removed airport's name is Dublin Airport."
字典的遍歷
可以使用for-in循環來遍歷某個字典中的鍵值對。每一個字典中的數據項都以(key, value)元組形式返回,并且我們可以使用臨時常量或者變量來分解這些元組
通過訪問keys或者values屬性,我們也可以遍歷字典的鍵或者值
for airportCode in airports.keys {
? ? print("Airport code: \(airportCode)")
}
// Airport code: YYZ
// Airport code: LHR
for airportName in airports.values {
? ? print("Airport name: \(airportName)")
}
// Airport name: Toronto Pearson
// Airport name: London Heathrow