Day 02 集合类型
2.1 Arrays(数组)
-
Question: 为什么 Swift 有数组?
-
Answer:
- Swift 提供字符串、整数、布尔值和双精度值用于存储单个值
如果要存储多个值,则需要使用数组
- 数组: 存储为单个值的值的集合
let john = "John Lennon" let paul = "Paul McCartney" let george = "George Harrison" let ringo = "Ringo Starr" // 字符串数组 let beatles = [john, paul, george, ringo]
- 通过索引(下标)取值,如果索引越界程序会crash
// 取第一个值 let first = beatles[0] // 数组越界访问下标 beatles[9]
- 数组可以使用类型注解声明
- Swift 数组可以任意大或小
[String], [Int], [Double], and [Bool] or other 自定义类型数组
- Swift 提供字符串、整数、布尔值和双精度值用于存储单个值
2.2 Set
-
- 集合就像数组一样是值的集合,除了它们有两个不同之处:
- 数据无序存放,无法像数组一样用索引去取值
- 数据不重复 colors 和 colors2 虽然声明不一致,但是实际存储的数据一致
let colors = Set(["red", "green", "blue"]) let colors2 = Set(["red", "green", "blue", "red", "blue"])
- Question: Array 和 Set 的差异性
- Answer:
- Array有序,Set 无序
- Array可存储重复数据,Set中的数据不重复
- Set 随机存储,无论集合大小,判断是否存在某条数据时间复杂度为O(1),底层是HashTable
而Array 中数据可重复,查询效率会只能遍历,时间复杂度为O(n)
判断集合中是否存在某条数据建议使用Set
2.3 Tuples
-
元组: 将多种数据类型存储在一个组合类型中,类似数组,但又有些许差异
- 元组在初始化时类型固定,无法修改
// 初始化一个元组,类型为:第一个元素是字符串类型,元素名为first,第二个元素是字符串,元素名为last var name = (first: "Taylor", last: "Swift")
- 无法增删改元素名称及类型
// ❌示例 修改元素类型 name.first = 10 // ❌示例 修改元素名称 name.age = 100
- 可以通过下标或者元素名称访问对应元素数据,不允许越界访问,不允许访问不存在的元素名称
// 通过下标访问第一个元素 name.0 // 通过元素名访问元素 name.first
-
Question: 元组和数组有什么区别?
-
Answer:
- 元组是一个key为字符串类型的固定Set,无法增删改 元素名称和类型,数组可以存储无限个同一种数据类型的集合
// tuple 固定类型set var website = (name: "Apple", url: "www.apple.com") // array 可变集合 var website = ["Apple", "www.apple.com"]
- 元组可以存储多种数据类型,数组只可以存储单一数据类型
// 元组元素类型多样性 var person = (name: "Paul", age: 40, isMarried: true) // 数组元素类型单一 var persons = ["Paul", "Eric"] var ages = [29, 30]
- 元组名称安全性
- 元组是一个key为字符串类型的固定Set,无法增删改 元素名称和类型,数组可以存储无限个同一种数据类型的集合
2.4 Arrays vs sets vs tuples
- 数组/Set/元组 比较类似但各自又有明确的用途
- 如果需要一个固定集合,元素名称具体,元素位置和类型精确,那么建议使用元组
let address = (house: 555, street: "Taylor Swift Avenue", city: "Nashville")
- 如果需要一个集合中的元素唯一,并且可以快速高效判断元素是否在集合中,那么建议使用Set
let set = Set(["aardvark", "astronaut", "azalea"])
- 如果需要一个集合只允许存储单一类型的元素,允许重复,更注重元素的顺序,并且元素数量可以变更,那么建议使用数组
let pythons = ["Eric", "Graham", "John", "Michael", "Terry", "Terry"]
- 如果需要一个固定集合,元素名称具体,元素位置和类型精确,那么建议使用元组
- Question: 在Swift中什么时候应该使用数组、集合或元组?
- Answer:
- 数组/Set/元组 用途上差异细微,因此如何选择正确的结构更高效存储数据尤为重要
- 数组 有序可重复
Set 无序 不重复
元组 元素名称/位置/类型都不可变 - 如果存储一系列无序 不重复的文本在一个集合中,建议使用Set
如果存储用户阅读的文章集合,主要关注是否被读过,无序用Set,有序用数组
如果存储一个有序可重复的高分游戏集合,建议用数组
如果存储一个顺序可预知的TODO List,建议用数组
如果存储精确的两个字符串或者一个字符串一个数字,或者Booleans 建议用元组
2.5 Dictionaries
-
字典和数组比较相似,但又有区别,字典不可以用下标存储或访问元素,字典使用字符串作为key存储元素
let heights = [ "Taylor Swift": 1.78, "Ed Sheeran": 1.73 ]
-
字典和数组一样都是使用大括号[],用逗号,来区分元素,
let users = ["eric", "wells"]
-
字典点类型注解需要标明类型在大括号中,用冒号区分键和值
let height: [String: Double] = ["height": 1.78] let name: [String: String] = ["name": "eric"]
-
Question: 为什么 Swift 既有字典又有数组?
-
Answer:
- 字典和数组都是存储一系列数据的集合,但字典用键值对存取元素,数组通过下标存取元素
- 字典无法确保key 是否存在,只能通过获取key对应的元素是否存在推断
2.6 Dictionary default values
- 如果字典中key对应的value不存在,则默认会返回nil,
Swift字典提供一个默认值选项,可以返回指定的数据let favoriteIceCream = [ "Paul": "Chocolate", "Sophie": "Vanilla" ] favoriteIceCream["Paul"] // Chocolate favoriteIceCream["Charlotte"] // nil favoriteIceCream["Charlotte" default: "unknow"] // unknow
- Question: 为什么Swift的字典提供默认值选项?
- Answer:
-
当访问字典中的key对应的value时,有时会返回nil,这样程序会出错,为了避免程序错误,Swift 提供默认值选项,返回预知的数据
-
示例字典存储学生的科目成绩,如果没找到对应科目的成绩会返回nil,这不符合我们的预期,可以加默认值0来处理
let results = [ "english": 100, "french": 85, "geography": 75 ] let historyResult = results["history", default: 0]
-
2.7 Creating empty collections
// 空字典
var teams = [String: String]()
// 更新字典
teams["Paul"] = "Red"
// 空 Int 数组
var results = [Int]()
// 空 字符串Set
var words = Set<String>()
// 空 Int Set
var numbers = Set<Int>()
// 空 字典
var scores = Dictionary<String, Int>()
// 空 数组
var results = Array<Int>()
2.8 Enumerations
- Eunm枚举,通常为了方便使用将一组有关联的数据类型组合在一起定义成枚举,比如接口返回结果成功和失败
let result = "failure" let result2 = "failed" let result3 = "fail"
- 上面代码中三个都代表失败,但丑陋无比,我们可以定义一个Enum 类型 的Result,防止用不同的字符串表达同样的意图
enum Result { case success case failure } Result.success // 成功 Result.failure // 失败
2.9 Eunm associate
-
枚举可以给一个或者多个case设置关联值,让case描述更详细
-
也可以给case 设置多个关联值
enum Activity { case bored case running case talking case singing } enum Activity { case bored case running(destination: String) case talking(topic: String) case singing(volume: Int) } let talking = Activity.talking(topic: "football")
-
Enum raw values
enum Planet: Int { case mercury case venus case earth case mars }
网友评论