【Swift官方文档】7.Swift集合类型

集合类型

使用数组、集合和字典来组织数据。Swift 提供了三种主要的集合类型:数组、集合和字典,用于存储值的集合。数组是有序的值集合。集合是无序的唯一值集合。字典是无序的键值对集合。

Swift 中的数组、集合和字典始终清晰地指明它们可以存储的值和键的类型。这意味着你无法错误地将不合类型的值插入集合中。这也意味着你可以对从集合中检索到的值的类型充满信心。

注意

Swift 的数组、集合和字典类型是作为通用集合实现的。有关通用类型和集合的更多信息,请参见通用类型。

集合的可变性

如果你创建一个数组、集合或字典,并将其赋值给一个变量,则创建的集合将是可变的。这意味着在创建后你可以通过添加、删除或更改集合中的项目来更改(或修改)该集合。如果将数组、集合或字典赋值给常量,则该集合是不可变的,其大小和内容不能更改。

注意

在所有不需要更改集合的情况下创建不可变集合是一个良好的实践。这样可以使你更容易理解代码,并使 Swift 编译器能够优化你创建的集合的性能。

数组

数组将相同类型的值存储在有序列表中。相同的值可以在数组中多次出现在不同的位置。

注意

Swift 的 Array 类型与 Foundation 的 NSArray 类桥接。

有关在 Foundation 和 Cocoa 中使用 Array 的更多信息,请参见 Array 和 NSArray 的桥接。

数组类型简写语法

Swift 数组的类型完全写作 Array<Element>,其中 Element 是数组允许存储的值的类型。你还可以将数组的类型简写为 [Element]。尽管这两种形式在功能上是相同的,但简写形式是首选的,并且在本指南中引用数组类型时使用简写形式。

创建空数组

你可以使用初始化器语法创建特定类型的空数组:

swift

复制代码

Swift 复制代码
var someInts: [Int] = []
print("someInts is of type [Int] with \(someInts.count) items.")
// 打印 "someInts is of type [Int] with 0 items."

注意,someInts 变量的类型从初始化器的类型推断为 [Int]

或者,如果上下文已经提供了类型信息,例如函数参数或已经有类型的变量或常量,你可以用空数组字面量(即 [])创建一个空数组:

swift

复制代码

Swift 复制代码
someInts.append(3)
// someInts 现在包含 1 个类型为 Int 的值
someInts = []
// someInts 现在是一个空数组,但仍然是类型 [Int]

创建带有默认值的数组

Swift 的 Array 类型还提供了一个初始化器,用于创建指定大小的数组,并将所有值设置为相同的默认值。你将适当类型的默认值(称为 repeating)和该值在新数组中重复的次数(称为 count)传递给此初始化器:

swift

复制代码

Swift 复制代码
var threeDoubles = Array(repeating: 0.0, count: 3)
// threeDoubles 的类型为 [Double],等于 [0.0, 0.0, 0.0]

通过将两个数组相加来创建数组

你可以通过使用加法运算符(+)将两个兼容类型的现有数组相加来创建一个新数组。新数组的类型是从你相加的两个数组的类型推断出来的:

swift

复制代码

Swift 复制代码
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]

使用数组字面量创建数组

你也可以使用数组字面量初始化数组,这是将一个或多个值写为数组集合的简写方式。数组字面量写作一系列值,使用逗号分隔,并被一对方括号包围:

swift

复制代码

Swift 复制代码
[<#value 1#>, <#value 2#>, <#value 3#>]

下面的示例创建了一个名为 shoppingList 的数组来存储字符串值:

swift

复制代码

Swift 复制代码
var shoppingList: [String] = ["Eggs", "Milk"]
// shoppingList 已初始化为两个初始项

shoppingList 变量被声明为"一个字符串值数组",写作 [String]。因为这个特定数组指定了值的类型为 String,所以它只允许存储字符串值。在这里,shoppingList 数组使用两个字符串值("Eggs" 和 "Milk")初始化,并写在数组字面量中。

注意

shoppingList 数组被声明为一个变量(使用 var 引导词),而不是常量(使用 let 引导词),因为在下面的示例中会向购物清单中添加更多项目。

在这个情况下,数组字面量只包含两个字符串值,没有其他内容。这与 shoppingList 变量的声明类型(一个只能包含字符串值的数组)相匹配,因此将数组字面量赋值给 shoppingList 是被允许的,以初始化 shoppingList 的两个初始项。

得益于 Swift 的类型推断,如果你使用一个包含相同类型值的数组字面量来初始化数组,则不必写出数组的类型。shoppingList 的初始化可以写得更短:

swift

复制代码

Swift 复制代码
var shoppingList = ["Eggs", "Milk"]

因为数组字面量中的所有值都是相同类型,Swift 可以推断出 [String]shoppingList 变量的正确类型。

访问和修改数组

你可以通过其方法和属性,或者使用下标语法访问和修改数组。

要找出数组中的项数,可以检查其只读的 count 属性:

swift

复制代码

Swift 复制代码
print("The shopping list contains \(shoppingList.count) items.")
// 打印 "The shopping list contains 2 items."

使用布尔值的 isEmpty 属性作为检查 count 属性是否等于 0 的快捷方式:

swift

复制代码

Swift 复制代码
if shoppingList.isEmpty {
    print("The shopping list is empty.")
} else {
    print("The shopping list isn't empty.")
}
// 打印 "The shopping list isn't empty."

你可以通过调用数组的 append(_:) 方法向数组的末尾添加新项:

swift

复制代码

Swift 复制代码
shoppingList.append("Flour")
// shoppingList 现在包含 3 项,有人正在做煎饼

或者使用加法赋值运算符(+=)附加一个或多个兼容项的数组:

swift

复制代码

Swift 复制代码
shoppingList += ["Baking Powder"]
// shoppingList 现在包含 4 项
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList 现在包含 7 项

使用下标语法检索数组中的值,传递你想检索的值的索引,立即在数组名称后面的方括号中:

swift

复制代码

Swift 复制代码
var firstItem = shoppingList[0]
// firstItem 等于 "Eggs"

注意

数组中的第一个项的索引为 0,而不是 1。Swift 中的数组总是以零为索引。

你可以使用下标语法更改给定索引处的现有值:

swift

复制代码

shoppingList[0] = "Six eggs" // 列表中的第一个项现在等于 "Six eggs",而不是 "Eggs"

当你使用下标语法时,指定的索引需要是有效的。例如,尝试写 shoppingList[shoppingList.count] = "Salt" 以尝试将项追加到数组末尾会导致运行时错误。

你还可以使用下标语法一次更改一系列值,即使替换的值集合的长度与要替换的范围不同。以下示例用 "Bananas" 和 "Apples" 替换 "Chocolate Spread"、"Cheese" 和 "Butter":

swift

复制代码

Swift 复制代码
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList 现在包含 6 项

要在指定索引处插入项,请调用数组的 insert(_:at:) 方法:

swift

复制代码

Swift 复制代码
shoppingList.insert("Maple Syrup", at: 0)
// shoppingList 现在包含 7 项
// "Maple Syrup" 现在是列表中的第一项

此调用 insert(_:at:) 方法在购物清单的最前面插入一个值为 "Maple Syrup" 的新项,索引为 0。

同样,你可以使用 remove(at:) 方法从数组中删除项。此方法删除指定索引处的项,并返回该项的值:

swift

复制代码

Swift 复制代码
let removedItem = shoppingList.remove(at: 0)
// removedItem 等于 "Maple Syrup"
// shoppingList 现在包含 6 项,"Maple Syrup" 已被移除

你还可以使用 removeLast() 方法从数组末尾删除最后一个项:

swift

复制代码

Swift 复制代码
let lastItem = shoppingList.removeLast()
// lastItem 等于 "Apples"
// shoppingList 现在包含 5 项

遍历数组

可以使用 for 循环来遍历数组中的每个项。Swift 的 for-in 循环可以用来遍历数组中的每个项:

swift

复制代码

Swift 复制代码
for item in shoppingList {
    print(item)
}
// 打印 "Six eggs"
// 打印 "Flour"
// 打印 "Baking Powder"
// 打印 "Bananas"
// 打印 "Cheese"

如果你还想获得每个项的索引,可以使用 enumerated() 方法与 for-in 循环一起使用:

swift

复制代码

Swift 复制代码
for (index, item) in shoppingList.enumerated() {
    print("Item \(index + 1): \(item)")
}
// 打印 "Item 1: Six eggs"
// 打印 "Item 2: Flour"
// 打印 "Item 3: Baking Powder"
// 打印 "Item 4: Bananas"
// 打印 "Item 5: Cheese"

集合

集合是一种无序的、唯一的值集合。集合中的值不能重复,这使得它们在需要确保值唯一的情况中非常有用。集合中的值可以是任何 Hashable 类型的值(例如字符串、数字或自定义结构体)。有关 Hashable 的更多信息,请参见集合。

注意

Swift 的 Set 类型与 Foundation 的 NSSet 类桥接。

集合类型简写语法

Swift 中的集合类型完全写作 Set<Element>,其中 Element 是集合允许存储的值的类型。可以将集合类型简写为 Set<Element>

创建空集合

可以使用初始化器语法创建特定类型的空集合:

swift

复制代码

Swift 复制代码
var letters = Set<Character>()
print("letters 是一个空的 Set<Character>,包含 \(letters.count) 项")
// 打印 "letters 是一个空的 Set<Character>,包含 0 项"

你也可以用集合字面量创建一个特定类型的集合。例如,下面的示例创建一个字符的集合:

swift

复制代码

Swift 复制代码
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres 的类型为 Set<String>

你也可以使用字面量创建一个包含数字的集合:

swift

复制代码

Swift 复制代码
var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
// favoriteGenres 的类型为 Set<String>

集合操作

可以使用多个方法和属性来操作集合,包括获取元素的数量、添加和删除元素等。与数组类似,集合也有一个只读属性 count,可以找到集合中项的数量:

swift

复制代码

Swift 复制代码
print("I have \(favoriteGenres.count) favorite music genres.")
// 打印 "I have 3 favorite music genres."

你可以使用 insert(_:) 方法向集合中添加新项:

swift

复制代码

Swift 复制代码
favoriteGenres.insert("Jazz")
// favoriteGenres 现在包含 4 项

要从集合中删除项,可以使用 remove(_:) 方法:

swift

复制代码

Swift 复制代码
if let removedGenre = favoriteGenres.remove("Rock") {
    print("\(removedGenre) 已从集合中移除。")
} else {
    print("集合中没有 Rock。")
}
// 打印 "Rock 已从集合中移除。"

要检查集合中是否包含某个项,可以使用 contains(_:) 方法:

swift

复制代码

Swift 复制代码
if favoriteGenres.contains("Funk") {
    print("我喜欢 Funk。")
} else {
    print("我不喜欢 Funk。")
}
// 打印 "我不喜欢 Funk。"

遍历集合

与数组一样,可以使用 for-in 循环遍历集合中的每个项。尽管集合是无序的,但每次遍历的结果都可以相同:

swift

复制代码

Swift 复制代码
for genre in favoriteGenres {
    print(genre)
}
// 结果无序,可能打印 "Classical"、"Hip hop"、"Jazz"

字典

字典是无序的键值对集合。字典中的每个值都通过其唯一的键进行访问。字典的键是唯一的,不能重复。

注意

Swift 的 Dictionary 类型与 Foundation 的 NSDictionary 类桥接。

字典类型简写语法

Swift 中的字典类型完全写作 Dictionary<Key, Value>,其中 Key 是字典中键的类型,Value 是字典中值的类型。你可以将字典的类型简写为 [Key: Value]

创建空字典

可以使用初始化器语法创建特定类型的空字典:

swift

复制代码

Swift 复制代码
var namesOfIntegers = [Int: String]()
print("namesOfIntegers 是一个空的 [Int: String] 字典,包含 \(namesOfIntegers.count) 项")
// 打印 "namesOfIntegers 是一个空的 [Int: String] 字典,包含 0 项"

创建字典

可以使用字典字面量创建字典。例如,下面的示例创建一个包含整数及其名称的字典:

swift

复制代码

Swift 复制代码
var namesOfIntegers = [0: "零", 1: "一", 2: "二"]

注意

Swift 会自动推断字典的类型为 [Int: String],因为字典字面量中的键是整数,而值是字符串。

访问和修改字典

与数组和集合一样,可以使用多种方法和属性访问和修改字典。可以使用字典的只读属性 count 查找字典中项的数量:

swift

复制代码

Swift 复制代码
print("namesOfIntegers 现在包含 \(namesOfIntegers.count) 项")
// 打印 "namesOfIntegers 现在包含 3 项"

要访问字典中的值,可以使用下标语法,传入要访问的键的值:

swift

复制代码

Swift 复制代码
let numberName = namesOfIntegers[2]
// numberName 等于 "二"

如果你访问的键在字典中不存在,结果将是 nil。可以使用可选绑定语法检查:

swift

复制代码

Swift 复制代码
if let numberName = namesOfIntegers[5] {
    print("数字 5 的名称是 \(numberName)")
} else {
    print("数字 5 不在字典中。")
}
// 打印 "数字 5 不在字典中。"

要添加或更改字典中的值,可以使用下标语法:

swift

复制代码

Swift 复制代码
namesOfIntegers[1] = "壹"
// namesOfIntegers[1] 现在等于 "壹"

namesOfIntegers[4] = "四"
// namesOfIntegers 现在包含 4 项,包括键 4 的新项

要删除字典中的项,可以使用 removeValue(forKey:) 方法:

swift

复制代码

Swift 复制代码
let oldValue = namesOfIntegers.removeValue(forKey: 2)
// oldValue 等于 "二"
// namesOfIntegers 现在只包含 3 项

遍历字典

与其他集合类型相同,可以使用 for-in 循环遍历字典中的每个键值对:

swift

复制代码

Swift 复制代码
for (number, name) in namesOfIntegers {
    print("\(number): \(name)")
}
// 打印:
// 0: 零
// 1: 壹
// 4: 四

如果你想要以特定顺序访问字典的键,可以使用 keys 属性和排序方法:

swift

复制代码

Swift 复制代码
for number in namesOfIntegers.keys.sorted() {
    print("\(number): \(namesOfIntegers[number]!)")
}
// 打印:
// 0: 零
// 1: 壹
// 4: 四
相关推荐
恩爸编程39 分钟前
探索 Nginx:Web 世界的幕后英雄
运维·nginx·nginx反向代理·nginx是什么·nginx静态资源服务器·nginx服务器·nginx解决哪些问题
Michaelwubo2 小时前
Docker dockerfile镜像编码 centos7
运维·docker·容器
远游客07132 小时前
centos stream 8下载安装遇到的坑
linux·服务器·centos
好像是个likun2 小时前
使用docker拉取镜像很慢或者总是超时的问题
运维·docker·容器
LIKEYYLL4 小时前
GNU Octave:特性、使用案例、工具箱、环境与界面
服务器·gnu
云云3214 小时前
搭建云手机平台的技术要求?
服务器·线性代数·安全·智能手机·矩阵
云云3215 小时前
云手机有哪些用途?云手机选择推荐
服务器·线性代数·安全·智能手机·矩阵
cominglately5 小时前
centos单机部署seata
linux·运维·centos
CircleMouse5 小时前
Centos7, 使用yum工具,出现 Could not resolve host: mirrorlist.centos.org
linux·运维·服务器·centos
Karoku0665 小时前
【k8s集群应用】kubeadm1.20高可用部署(3master)
运维·docker·云原生·容器·kubernetes