【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

复制代码

shoppingList0 = "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: 四
相关推荐
大树883 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠3 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质4 小时前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
小宇宙Zz4 小时前
Maven依赖冲突
java·服务器·maven
Inhand陈工5 小时前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智5 小时前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_5 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
古城小栈6 小时前
Unix 与 Linux 异同小叙
linux·服务器·unix
施努卡机器视觉6 小时前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造
程序猿阿伟6 小时前
《Chrome离线扩展安装的底层逻辑与场景落地指南》
服务器·网络·chrome