集合类型
Swift
语言提供Array
(有序数据集)、Set
(无序不重复数据集)和Dictionary
(无序键值对)三种基本的集合类型用来存储集合数据
Arrays
、Sets
和Dictionaries
中存储的数据值类型必须明确
Swift 的Arrays、Sets和Dictionaries类型被实现为泛型集合
。
数组类型
Array<Int>
简化形式[Int]
集合类型Set<Int>
无简化形式
字典类型Dictionary<Int, String>
简化[Int: String]
Array继承RangeReplaceableCollection
协议 因此可以使用我们前面说的index索引
和insert方法
创建空的集合数据 就是类型()
集合可变性
当集合为变量,集合是可变的,当不需要集合改变时建议创建为不可变的let,有利于优化
数组Array
存储同一类型值,可以重复
注意
Swift 的Array类型被桥接到Foundation中的NSArray类
创建空数组
var someInts = [Int]()//创建空数组
通过构造函数的类型,数组可以推断为[Int]
//创建特定数据类型的空数组
var someInt1 = [[Int]]()//创建类型为整形数组的空数组
数组的类型表达为 [Int] 表示一个类型为[Int]的数组
someInts.append(3)
//可以从上面推断出数组为Int类型数组,因此可以直接创建空数组
someInts = []
//直接创建空数组
带有默认值的数组
创建特定大小并且所有数据都被默认构造数组方法
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]
// shoppingList 已经被构造并且拥有两个初始项。
var shoppingList: [String] = ["Eggs", "Milk"]
var shoppingList = ["Eggs", "Milk"] //可以不用声明类型 可以推断为String类型
访问和修改数组
- 使用数组的只读
count
属性来获取数组中数据项数量 用布尔
isEmpty
检查数组是否为空 即count
属性是否为0
if shoppingList.isEmpty { print("The shopping list is empty.")
} else {
print("The shopping list is not empty.")
}
// 打印“The shopping list is not empty.”(shoppinglist 不是空的)使用
append(_:)
方法在数组后添加一个新的数组项shoppingList.append("Flour") //只能添加一项
用加法赋值运算符
+=
在数组后添加一个或多个相同类型数据项
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
用下标来获取数组中数据项
var firstItem = shoppingList[0]//获取数组中第一项
用下标改变一个或多个下标索引对应色数据值
shoppingList[0] = "Six eggs"// shoppingList[4...6] = ["Bananas", "Apples"]//改变一系列值 即使新数据和原 有数据的数量不一致
注意:
不能用下标访问的形式在数组尾部添加新项
用
insert(_:at:)
方法在某个索引之前添加新的数据项移除
使用remove(at:)
方法来移除数组中的某一项,并返回被移除的值let mapleSyrup = shoppingList.remove(at: 0) // 索引值为0的数据项被移除
// mapleSyrup 常量的值等于被移除数据项“Maple Syrup”removeLast()
移除数组最后一项
removeFirst()
移除数组最后一项注意
通过约见执行访问或修改数组数据,会引起运行期错误
遍历数组
用for-in
进行遍历
for item in shoppingList {
print(item)//单独的变量或常量可以直接print
}
用数组的enumerated()
,在遍历时获取每个数据项的索引和值,返回由索引和数组值组成的元组
for (index, value) in shoppingList.enumerated() {
print("Item \(String(index + 1)): \(value)")
}
/*
shoppingList.enumerated()返回就是一个sorted后 以元组形式返回
*/
数组也继承了
collection
协议
集合Set
存储相同类型并且没有确定顺序的值
注意
Swift的Set类型被桥接到Foundation中的NSSet类
集合类型的哈希值
一个类型为了存储在集合中,该类型必须是可哈希化的,即该类型必须提供一个方法来计算它的哈希值(哈希值是Int
类型的),相等对象的哈希值必须相同(a==b因此a.hashValue == b.hashValue
).
Swift 的所有基本类型(比如String , Int , Double 和 Bool
)默认都是可哈希化的,可以作为集合的值的类型或者字典的键的类型。没有关联值的枚举成员值默认也是可哈希化的。
注意
可以自定义一个遵循
Hashable
协议的自定义类型,作为集合值类型或者字典键的类型。这个协议需要提供一个Int
的可读属性hashValue
.hashValue
属性返回的值并不需要在同一程序的不同执行周期或者不同程序之间保持相同。
其次,因为Hashable
协议符合Equatable
协议,所以遵循该协议的类型也必须提供一个"是否相等"运算符(==
)的实现。
集合类型写法/表达
Swift 中的Set
类型被写为 Set<Element>
(Element
表示Set
中允许存储的类型),它并没有类似数组的等价简化形式
空的集合
var letters = Set<Character>()
letters.insert("a")//通过这 我们可以推断出为一个Set<Character>类型集合
letters = []//我们可以直接设置其为空的Set 其类型还是Set<Character>
用数组字面量创建集合
//有三个初始值
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
我们用数组字面量的形式初始化这个Set
.我们从数组字面量没有办法推断出为Set
类型,因此必须显示声明,但是可以推断出Set中元素类型,因此我们可以简化为
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
访问和修改一个集合
1.只读属性count
获取集合中个数
2.布尔属性isEmpty
作为一个缩写形式去检查count
属性是否为 0
3.insert(_:)
方法来添加一个新元素
favoriteGenres.insert("Jazz")
/**
返回一个元组(inserted: Bool, memberAfterInserted: String)
*/
4.remove(_:)
方法去删除一个元素
如果删除的是集合中的一个元素,则删除并返回它,但是如果集合中不包含它,就返回nil
removeAll()
删除所有元素
5.contains(_:)
方法去检查Set
中是否包含一个特定的值
if favoriteGenres.contains("Funk") {
print("I get up on the good foot.")
} else {
print("It's too funky in here.")
}
6.用for-in
遍历
for genre in favoriteGenres {
print("\(genre)")
}
7.排序
Set
类型没有确定的顺序,为了按照特定顺序来遍历一个Set
中的值可以使用sorted()
方法,它将返回一个有序数组,这个数组的元素排列顺序由操作符'<'
对元素进行比较的结果来确定
for genre in favoriteGenres.sorted() {
print("(genre)")
}
sorted()后返回的是数组
sorted()返回排序后数组 数据源不变 sort()不返回数组将数据源变为排序后的数组(Set没有这方法,Array有)
集合操作
基本集合操作
用intersection(_:)
计算两个集合相交部分 ---- 交集
用symmetricDifference(_:)
计算两个集合中不同部分 ----
用union(_:)
方法合并两个集合 --- 并集
用subtracting(_:)
方法根据在本集合不在另外集合中的部分 --- 补集
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
oddDigits.union(evenDigits).sort()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersection(evenDigits).sorted()
// []
oddDigits.subtracting(singleDigitPrimeNumbers).sorted()
// [1, 9]
oddDigits. symmetricDifference(singleDigitPrimeNumbers).sorted()
// [1, 2, 9]
集合成员关系以及相等
- 用
==
判断两个集合是否包含完全相同的值 - 用
isSubset(of:)
判断是不是两外一个集合的子集 - 用
isSuperset(of:)
判断另外一个集合是不是本集合的子集 - 用
isStrictSubset(of:)
或isStrictSuperset(of:)
判断一个集合是否是另外一个集合的子集合或者父集合并且两个集合并不相等 - 用
isDisjoint(with:)
判断两个集合是否没有交集(没有相同的值)
字典
存储多个相同类型的值的容器
字典类型表达语法
Swift
的字典使用Dictionary<Key, Value>
定义,Key
是键的类型,Value
是值所对应的数据类型
[Key: Value]
通常我们使用这种简化形式
一个字典的 Key 类型必须遵循
Hashable
协议,就像Set
的值类型,因为在字典中键也是唯一的,需要利用哈希值进行判断相等
创建一个空字典
var namesOfIntegers = [Int: String]()//创建一个[Int: String] 类型的空字典
如果上下文已经知道类型信息
namesOfIntegers = [:]//创建一个[Int: String] 类型的空字典
用字典字面量创建字典
var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
//因为swift可以推断出为[String : String]类型 因此可以不同显示声明
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
访问和修改字典
1.只读属性count
来获取字典的数据项数量
print("The dictionary of airports contains (airports.count) items.")
// 打印 "The dictionary of airports contains 2 items."(这个字典有两个数据项)
2.isEmpty
作为一个缩写形式去检查count
属性是否为 0
3.可以在字典中使用下标语法来添加新的数据项
4.在字典中使用下标语法来改变特定键对应的值
airports["LHR"] = "London"
//若不存在键"LHR" 即为添加新的数据项 否则为改变键对应值
5.updateValue(_:forKey:)
方法作为替代下标语法的方式,可以设置或者更新特定键对应的值(当存在键时即为更新值 否则为设置值)
updateValue(_:forKey:)
方法会返回更新值之前的原值,所以对应值的类型的可选值(因为可能没有oldvalue),可以根据此来判断更新是否成功
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
print("The old value for DUB was (oldValue).")
}
// 输出 "The old value for DUB was Dublin."
6.下标语法来在字典中检索特定键对应的值,因为可能不存在这个键,因此返回的为可选类型
if let airportName = airports["DUB"] {
print("The name of the airport is (airportName).")
} else {
print("That airport is not in the airports dictionary.")
}
7.通过给某个键的对应值赋值为nil
来从字典里移除一个键值对
airports["APL"] = "Apple Internation"
// "Apple Internation" 不是真的 APL 机场, 删除它
airports["APL"] = nil
// APL 现在被移除了
8.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.")
}
字典遍历
for-in
遍历字典中的键值对,字典中的数据项都以(key, value)
元组形式返回
for (airportCode, airportName) in airports {
print("\(airportCode): \(airportName)")
}
通过访问keys
或者values
属性,我们也可以遍历字典的键或者值
for airportCode in airports.keys {
print("Airport code: (airportCode)")
}
for airportName in airports.values {
print("Airport name: (airportName)")
}
我们可以直接使用keys
或者values
属性构造一个新数组
let airportCodes: [String] = airports.keys
// airportCodes 是 ["YYZ", "LHR"]
let airportNames: [String] = airports.values
// airportNames 是 ["Toronto Pearson", "London Heathrow"]
let airportCodes = airports.keys.sorted()
//创建键或者值的新数组
Swift
的字典类型是无序集合类型。为了以特定的顺序遍历字典的键或值,可以对字典的keys
或values
属性使用sorted()
方法