Swift 提供了三種主要的集合類型(collection types),所謂的數組(arrays)、集合(sets)還有字典(dictionaries),用來存儲值的集合。數組是有序的值集合。集合是唯一值的無序集合。字典是無序的鍵值對集合。
集合類型的可變性
如果創建的一個數組、集合、字典,並且賦值給一個變量,那麼創建的集合就是可變的。這就意味着你隨後可以添加、移除或者改變集合中的元素來改變集合。如果你把數組、集合或者字典賦值給一個常量,則集合就成不了不可變的,它的大小和內容都是不能被改變的。在集合不需要改變的情況下創建你不可變集合是個不錯的選擇。這樣做可以允許 Swift 編譯器優化你創建的集合性能。
數組(arrays)
數組以有序的方式來存儲相同類型的值。相同類型的值可以在數組的不同地方多次出現。
- 數組類型簡寫語法
Swift 數組的類型完成寫法是 Array, Element 數數組允許存入的值的類型。你同樣可以簡寫數組的類型爲 [ Element ]。儘管兩種格式功能上相同,我們更推存簡寫並且全書涉及到數組類型的時候都會使用簡寫。
- 創建一個數組
你可以使用確定類型通過初始化器語法來創建一個數組:
var shoppingList = [String]()
var shoppingList: [String] = ["Eggs", "Milk"]
var shoppingList = ["Eggs", "Milk"]
- 訪問和修改數組
可以通過數組的方法和屬性來修改數組,或者用使用下標腳本語法。
要得出數組中元素的數量,檢查只讀的 count 屬性:
var intValues = [Int]()
print(intValues.count)
//輸出:0
使用布爾量 isEmpty 屬性來作爲檢查 count 屬性是否等於 0 的快捷方式:
var intValues = [Int]()
if intValues.isEmpty{
print("數組是空的")
}else{
print("數組不是空的")
}
//輸出:數組是空的
你可以通過 append( _ : ) 方法給數組末尾添加新的元素:
var intValues = [Int]()
intValues.append(1)
print(intValues)
//輸出 [1]
另外,可以使用加賦值運算符( += )來在數組末尾加一個或者多個同類型元素
var intValues = [Int]()
intValues+=[1]
print(intValues)
//輸出 [1]
通過下標腳本語法來從數組當中取回一個值,在緊跟數組名後的方括號內傳入你想要取回的值的索引:
var intValues = [Int]()
intValues+=[1]
let a = intValues[0]
print(a)
//輸出 1
你可以使用下標腳本語法來改變給定索引中已經存在的值:
var intValues = [Int]()
intValues+=[1]
intValues[0] = 2
print(intValues)
//輸出 [2]
要把元素插入到特定的索引位置,調用數組的 insert(_:at:)方法:
var intValues = [Int]()
intValues.append(1)
intValues.insert(2, at: 1)
print(intValues)
//輸出 [1, 2]
你可以使用 remove(at:)方法來移除一個元素。這個方法移除特定索引的元素並且返回它(儘管你不需要的話可以無視返回的值)
var intValues = [Int]()
intValues.append(1)
intValues.insert(2, at: 1)
let a = intValues.remove(at: 1)
print(a)
//輸出2
如果你想要移除數組最後一個元素,使用 removeLast()方法而不是 remove(at:)方法以避免查詢數組的 count屬性。與 remove(at:)方法相同, removeLast()返回刪除了的元素
- 遍歷一個數組
你可以用 for-in循環來遍歷整個數組中值的集合:
let names = ["dapeng","dashuai","damei","daqiang"]
for name in names {
print(name)
}
輸出
dapeng
dashuai
damei
daqiang
如果你需要每個元素以及值的整數索引,使用 enumerated()方法來遍歷數組。enumerated()方法返回數組中每一個元素的元組,包含了這個元素的索引和值。你可以分解元組爲臨時的常量或者變量作爲遍歷的一部分:
let names = ["dapeng","dashuai","damei","daqiang"]
for (index,value) in names.enumerated() {
print("索引:\(index) "+"值:\(value)")
}
輸出
索引:0 值:dapeng
索引:1 值:dashuai
索引:2 值:damei
索引:3 值:daqiang
集合(sets)
集和(sets)將同一類型且不重複的值無序地儲存在一個集合當中。當元素的順序不那麼重要的時候你就可以使用集合來代替數組,或者你需要確保元素不會重複的時候
- 集合類型語法
Swift 的集合類型寫做 Set< Element >,這裏的 Element是集合要儲存的類型。不同與數組,集合沒有等價的簡寫。
- 創建並初始化一個集合
你可以使用初始化器語法來創建一個確定類型的空集合:
var stringSet = Set<String>()
var stringSet:Set<String> = ["11","33"]
var stringSet:Set = ["211","985"]
集合類型不能從數組字面量推斷出來,所以 Set類型必須被顯式地聲明。總之,由於 Swift 的類型推斷,你不需要在使用包含相同類型值的數組字面量初始化集合的時候寫集合的類型。
- 訪問和修改集合
你可以通過集合的方法和屬性來訪問和修改集合。
要得出集合當中元素的數量,檢查它的只讀 count屬性:
var stringSet:Set = ["11","22","33","44"]
if stringSet.isEmpty {
print("集合是空")
}else{
print("集合不是空")
}
//輸出:集合不是空
你可通過調用 insert(_:)方法來添加一個新的元素到集合:
var stringSet:Set = ["11","22","33","44"]
stringSet.insert("55")
你可以通過調用集合的 remove(_:)方法來從集合當中移除一個元素,如果元素是集合的成員就移除它,並且返回移除的值,如果集合沒有這個成員就返回 nil。另外,集合當中所有的元素可以用 removeAll()一次移除。
var stringSet:Set = ["11","22","33","44"]
stringSet.remove("11")
要檢查集合是否包含了特定的元素,使用 contains(_:)方法。
var stringSet:Set = ["11","22","33","44"]
if stringSet.contains("11") {
print("包含")
}
//輸出:包含
- 遍歷集合
你可以在 for-in循環裏遍歷集合的值。
var stringSet:Set = ["11","22","33","44"]
for stringVal in stringSet {
print(stringVal)
}
輸出
11
44
33
22
Swift 的 Set類型是無序的。要以特定的順序遍歷集合的值,使用 sorted()方法,它把集合的元素作爲使用 < 運算符排序了的數組返回。
var stringSet:Set = ["11","22","33","44"]
for stringVal in stringSet.sorted() {
print(stringVal)
}
輸出
11
22
33
44
- 執行集合操作
你可以高效地執行基本地集合操作,比如合併兩個集合,確定兩個集合共有哪個值,或者確定兩個集合是否包含所有、某些或沒有相同的值。
1.使用 intersection(:)方法來創建一個只包含兩個集合共有值的新集合;
2.使用 symmetricDifference(:)方法來創建一個只包含兩個集合各自有的非共有值的新集合;
3.使用 union(:)方法來創建一個包含兩個集合所有值的新集合;
4.使用 subtracting(:)方法來創建一個兩個集合當中不包含某個集合值的新集合。
例如:
var intA:Set = [1,2,3,4]
var intB:Set = [3,4,5,6]
intA.intersection(intB).sorted()
// [3,4]
intA.symmetricDifference(intB).sorted()
// [1,2,5,6]
intA.union(intB).sorted()
// [1,2,3,4,5,6]
intA.subtracting(intB).sorted()
//[1,2]
1.使用“相等”運算符 ( == )來判斷兩個集合是否包含有相同的值;
2.使用 isSubset(of:) 方法來確定一個集合的所有值是被某集合包含;
3.使用 isSuperset(of:)方法來確定一個集合是否包含某個集合的所有值;
4.使用 isStrictSubset(of:) 或者 isStrictSuperset(of:)方法來確定是個集合是否爲某一個集合的子集或者超集,但並不相等;
5.使用 isDisjoint(with:)方法來判斷兩個集合是否擁有完全不同的值。
例如:
var intA:Set = [1,2,3,4]
var intB:Set = [3,4,5,6]
var intC:Set = [1,2]
var intD:Set = [8,9]
intA == intB
//false
intC.isSubset(of: intA)
//true
intA.isSuperset(of: intC)
//true
intA.isStrictSuperset(of: intC)
//true
intA.isDisjoint(with: intD)
//true
字典(dictionaries)
字典儲存無序的互相關聯的同一類型的鍵和同一類型的值的集合。每一個值都與唯一的鍵相關聯,它就好像這個值的身份標記一樣。不同於數組中的元素,字典中的元素沒有特定的順序。當你需要查找基於特定標記的值的時候使用字典,很類似現實生活中字典用來查找特定字的定義。
- 字典類型簡寫語法
Swift 的字典類型寫全了是這樣的:Dictionary,其中的 Key是用來作爲字典鍵的值類型, Value就是字典爲這些鍵儲存的值的類型。
你同樣可以用簡寫的形式來寫字典的類型爲 [Key: Value]。儘管兩種寫法是完全相同的,但本書所有提及字典的地方都會使用簡寫形式。
- 創建一個字典
var res = [String:String]()
var res:[String:String] = ["name":"dapeng","age":"18"]
var res = ["name":"dapeng","age":"18"]
- 訪問和修改字典
你可以通過字典自身的方法和屬性來訪問和修改它,或者通過使用下標腳本語法。
如同數組,你可以使用 count只讀屬性來找出 Dictionary擁有多少元素:
var res = ["name":"dapeng","age":"18"]
print(res.count)
//輸出:2
使用布爾量 isEmpty屬性作爲檢查 count屬性是否等於 0的快捷方式:
var res = ["name":"dapeng","age":"18"]
if !res.isEmpty {
print("字典不爲空")
}
//輸出:字典不爲空
你可以用下標腳本給字典添加新元素。使用正確類型的新鍵作爲下標腳本的索引,然後賦值一個正確類型的值,或者可以使用下標腳本語法來改變特定鍵關聯的值:
var res = ["name":"dapeng","age":"18"]
res["level"] = "高" //添加新值
res["level"] = "非常高" //修改值
作爲下標腳本的代替,使用字典的 updateValue( :forKey:)方法來設置或者更新特點鍵的值。就像上邊下標腳本的栗子, updateValue( :forKey:)方法會在鍵沒有值的時候設置一個值,或者在鍵已經存在的時候更新它。總之,不同於下標腳本, updateValue(_:forKey:)方法在執行更新之後返回舊的值。這允許你檢查更新是否成功。
updateValue(_:forKey:)方法返回一個字典值類型的可選項值。比如對於儲存 String值的字典來說,方法會返回 String?類型的值,或者說“可選的 String”。這個可選項包含了鍵的舊值如果更新前存在的話,否則就是 nil:
var res = ["name":"dapeng","age":"18"]
if let value = res.updateValue("high", forKey: "age") {
print("舊值:\(value)")
}else{
print("這是插入")
}
//輸出:舊值:18
你同樣可以使用下標腳本語法來從字典的特點鍵中取回值。由於可能請求的鍵沒有值,字典的下標腳本返回可選的字典值類型。如果字典包含了請求的鍵的值,下標腳本就返回一個包含這個鍵的值的可選項。否則,下標腳本返回 nil :
var res = ["name":"dapeng","age":"18"]
if let value = res["age"] {
print(value)
}
//輸出:18
你可以使用下標腳本語法給一個鍵賦值 nil來從字典當中移除一個鍵值對:
var res = ["name":"dapeng","age":"18"]
res["age"] = nil
print(res)
//輸出:["name": "dapeng"]
另外,使用 removeValue(forKey:)來從字典裏移除鍵值對。這個方法移除鍵值對如果他們存在的話,並且返回移除的值,如果值不存在則返回 nil:
var res = ["name":"dapeng","age":"18"]
if let val = res.removeValue(forKey: "age") {
print(val)
}
//輸出:18
- 遍歷字典
你可以用 for-in循環來遍歷字典的鍵值對。字典中的每一個元素返回爲 (key, value)元組,你可以解開元組成員到臨時的常量或者變量作爲遍歷的一部分:
var res = ["name":"dapeng","age":"18"]
for (key,val) in res {
print("鍵:\(key), 值:\(val)")
}
//輸出
//鍵:name, 值:dapeng
//鍵:age, 值:18
你同樣可以通過訪問字典的 keys和 values屬性來取回可遍歷的字典的鍵或值的集合:
var res = ["name":"dapeng","age":"18"]
for key in res.keys {
print(key)
}
for val in res.values {
print(val)
}
如果你需要和接收 Array實例的 API 一起使用字典的鍵或值,就用 keys或 values屬性來初始化一個新數組:
var res = ["name":"dapeng","age":"18"]
let keys = [String](res.keys)
//["age", "name"]
let vals = [String](res.values)
//["dapeng", "18"]
Swift 的 Dictionary類型是無序的。要以特定的順序遍歷字典的鍵或值,使用鍵或值的 sorted()方法。