Swift 中 Array 的简单介绍,方便初学者快速入门
目录
基础概念
Array 是 Swift 中的泛型集合类型,用于存储有序的元素集合。
特点
- 有序性:元素按照插入顺序排列
- 可重复:允许存储重复的元素
- 类型安全:编译时类型检查
-
可变性:使用
var
声明可修改,使用let
声明不可修改
性能特征
- 随机访问:O(1) 时间复杂度
- 插入/删除:O(n) 时间复杂度(在末尾操作除外)
- 内存效率:连续内存存储
声明和初始化
基本语法
// 显式类型声明
let ints: Array<Int> = [1, 2, 3, 4, 5]
let strings: [String] = ["one", "two", "three"]
// 类型推断
let numbers = [1, 2, 3, 4, 5] // 自动推断为 [Int]
let words = ["hello", "world"] // 自动推断为 [String]
空数组初始化
var emptyInts: [Int] = []
var emptyStrings = [String]()
var emptyDoubles = Array<Double>()
重复元素初始化
let repeated = Array(repeating: 0, count: 5) // [0, 0, 0, 0, 0]
let repeatedStrings = Array(repeating: "default", count: 3) // ["default", "default", "default"]
范围初始化
let rangeArray = Array(1...10) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let rangeArray2 = Array(1..<6) // [1, 2, 3, 4, 5]
数组属性
基本属性
let sampleArray = [1, 2, 3, 4, 5]
print(sampleArray.count) // 5 - 元素个数
print(sampleArray.isEmpty) // false - 是否为空
print(sampleArray.capacity) // 当前分配的容量
元素访问
// 安全访问(返回可选值)
print(sampleArray.first) // Optional(1)
print(sampleArray.last) // Optional(5)
// 强制访问(需要确保数组不为空)
print(sampleArray.first!) // 1
print(sampleArray.last!) // 5
// 索引访问
print(sampleArray[2]) // 3
数组操作
添加元素
var mutableArray = [1, 2, 3]
// 在末尾添加
mutableArray.append(4) // [1, 2, 3, 4]
mutableArray += [5, 6] // [1, 2, 3, 4, 5, 6]
// 在指定位置插入
mutableArray.insert(0, at: 0) // [0, 1, 2, 3, 4, 5, 6]
删除元素
var deleteArray = [1, 2, 3, 4, 5, 6]
// 删除指定索引的元素
let removed = deleteArray.remove(at: 2) // 返回被删除的元素 3
print(deleteArray) // [1, 2, 4, 5, 6]
// 删除第一个元素
let firstRemoved = deleteArray.removeFirst() // 返回 1
print(deleteArray) // [2, 4, 5, 6]
// 删除最后一个元素
let lastRemoved = deleteArray.removeLast() // 返回 6
print(deleteArray) // [2, 4, 5]
// 删除所有元素
deleteArray.removeAll()
print(deleteArray) // []
替换元素
var replaceArray = [1, 2, 3, 4, 5]
replaceArray[2] = 10 // [1, 2, 10, 4, 5]
// 替换范围
replaceArray[1...3] = [20, 30, 40] // [1, 20, 30, 40, 5]
数组遍历
基本遍历
let traverseArray = ["apple", "banana", "orange", "grape"]
// for-in 循环
for item in traverseArray {
print(item)
}
// 带索引的遍历
for (index, item) in traverseArray.enumerated() {
print("索引 \(index): \(item)")
}
高级遍历
// 使用 indices 遍历索引
for index in traverseArray.indices {
print("索引 \(index): \(traverseArray[index])")
}
// 使用 stride 遍历
for index in stride(from: 0, to: traverseArray.count, by: 2) {
print("偶数索引 \(index): \(traverseArray[index])")
}
// 反向遍历
for item in traverseArray.reversed() {
print(item)
}
// 带索引的反向遍历
for (index, item) in traverseArray.enumerated().reversed() {
print("反向索引 \(index): \(item)")
}
数组方法
排序
let methodArray = [3, 1, 4, 1, 5, 9, 2, 6]
// 初始排序
var sortArray = methodArray
sortArray.sort() // 升序排序
sortArray.sort(by: <) // 升序排序
sortArray.sort(by: >) // 降序排序
// 返回新数组的排序
let sortedArray = methodArray.sorted() // 不改变原数组
查找
let searchArray = ["apple", "banana", "orange", "grape"]
// 查找元素是否存在
let containsApple = searchArray.contains("apple") // true
// 查找元素索引
if let index = searchArray.firstIndex(of: "banana") {
print("banana 的索引: \(index)") // 1
}
// 查找满足条件的第一个元素
if let firstLong = searchArray.first(where: { $0.count > 5 }) {
print("第一个长度大于5的元素: \(firstLong)") // "banana"
}
函数式编程方法
let filterArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// 过滤
let evenNumbers = filterArray.filter { $0 % 2 == 0 } // [2, 4, 6, 8, 10]
// 映射
let doubled = filterArray.map { $0 * 2 } // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
// reduce
let sum = filterArray.reduce(0, +) // 55
let product = filterArray.reduce(1, *) // 3628800
// flatMap
let nestedArray = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
let flattened = nestedArray.flatMap { $0 } // [1, 2, 3, 4, 5, 6, 7, 8, 9]
数组切片
基本切片
let sliceArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
let firstThree = sliceArray[0..<3] // [0, 1, 2]
let lastThree = sliceArray[7...9] // [7, 8, 9]
let middle = sliceArray[3...6] // [3, 4, 5, 6]
使用 prefix 和 suffix
let prefix3 = sliceArray.prefix(3) // [0, 1, 2]
let suffix3 = sliceArray.suffix(3) // [7, 8, 9]
// 条件切片
let evenPrefix = sliceArray.prefix { $0 % 2 == 0 } // [0]
多维数组
二维数组
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(matrix[0]) // [1, 2, 3]
print(matrix[1][1]) // 5
创建多维数组
var emptyMatrix = Array(repeating: Array(repeating: 0, count: 3), count: 3)
遍历多维数组
for (rowIndex, row) in matrix.enumerated() {
for (colIndex, element) in row.enumerated() {
print("matrix[\(rowIndex)][\(colIndex)] = \(element)")
}
}
性能优化
预分配容量
var optimizedArray = [Int]()
optimizedArray.reserveCapacity(1000) // 预分配1000个元素的容量
批量操作
var batchArray = [Int]()
batchArray.reserveCapacity(100)
// 批量添加(比逐个添加更高效)
batchArray.append(contentsOf: 1...100)
延迟计算
let lazyArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let lazyResult = lazyArray.lazy
.filter { $0 % 2 == 0 }
.map { $0 * $0 }
.prefix(3)
print(Array(lazyResult)) // [4, 16, 36]
安全性和错误处理
边界检查
let safeArray = [1, 2, 3, 4, 5]
// 安全的索引访问
if safeArray.indices.contains(10) {
let element = safeArray[10]
} else {
print("索引超出范围")
}
可选绑定
if let firstElement = safeArray.first {
print("第一个元素: \(firstElement)")
}
if let lastElement = safeArray.last {
print("最后一个元素: \(lastElement)")
}
条件删除
var conditionalArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// 删除所有偶数
conditionalArray.removeAll { $0 % 2 == 0 }
print(conditionalArray) // [1, 3, 5, 7, 9]
高级用法
数组比较
let array1 = [1, 2, 3]
let array2 = [1, 2, 3]
let array3 = [1, 2, 4]
print(array1 == array2) // true
print(array1 == array3) // false
数组连接
let arrayA = [1, 2, 3]
let arrayB = [4, 5, 6]
let combined = arrayA + arrayB // [1, 2, 3, 4, 5, 6]
自定义扩展
// 数组分块
extension Array {
func chunked(into size: Int) -> [[Element]] {
return stride(from: 0, to: count, by: size).map {
Array(self[$0..<Swift.min($0 + size, count)])
}
}
}
let chunkArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let chunks = chunkArray.chunked(into: 3) // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
// 数组去重(保持顺序)
extension Array where Element: Hashable {
func removingDuplicates() -> [Element] {
var seen = Set<Element>()
return filter { seen.insert($0).inserted }
}
}
let orderedArray = [1, 2, 2, 3, 3, 3, 4, 5, 5]
let uniqueOrdered = orderedArray.removingDuplicates() // [1, 2, 3, 4, 5]
实际应用示例
学生成绩管理
struct Student {
let name: String
let score: Int
}
let students = [
Student(name: "Alice", score: 85),
Student(name: "Bob", score: 92),
Student(name: "Charlie", score: 78),
Student(name: "Diana", score: 95),
Student(name: "Eve", score: 88)
]
// 按成绩排序
let sortedStudents = students.sorted { $0.score > $1.score }
// 计算平均分
let averageScore = students.map { $0.score }.reduce(0, +) / students.count
购物车示例
struct Product {
let name: String
let price: Double
let quantity: Int
}
var cart = [
Product(name: "苹果", price: 5.0, quantity: 3),
Product(name: "香蕉", price: 3.0, quantity: 2),
Product(name: "橙子", price: 4.0, quantity: 1)
]
// 计算总价
let totalPrice = cart.map { $0.price * Double($0.quantity) }.reduce(0, +)
// 添加商品
cart.append(Product(name: "葡萄", price: 8.0, quantity: 1))
// 移除特定商品
cart.removeAll { $0.name == "香蕉" }
数据分析
let dataPoints = [23, 45, 67, 89, 12, 34, 56, 78, 90, 11]
// 统计信息
let minValue = dataPoints.min() ?? 0
let maxValue = dataPoints.max() ?? 0
let sumValue = dataPoints.reduce(0, +)
let average = Double(sumValue) / Double(dataPoints.count)
// 数据分组
let grouped = Dictionary(grouping: dataPoints) { $0 / 20 }
最佳实践
1. 类型安全
- 始终使用明确的类型声明
- 利用 Swift 的类型推断功能
2. 性能考虑
- 对于频繁修改的数组,使用
var
声明 - 预分配容量以提高性能
- 使用批量操作而不是循环
3. 内存管理
- 及时清理不需要的数组引用
- 避免循环引用
4. 错误处理
- 始终检查数组边界
- 使用可选绑定进行安全访问
5. 代码可读性
- 使用有意义的变量名
- 适当使用注释
- 遵循 Swift 编码规范
常见陷阱
1. 修改常量数组
// 错误示例
let constantArray = [1, 2, 3]
// constantArray.append(4) // 编译错误
// 正确做法
var mutableArray = [1, 2, 3]
mutableArray.append(4) // 正确
2. 数组越界
// 错误示例
let boundsArray = [1, 2, 3]
// let element = boundsArray[5] // 运行时错误
// 正确做法
if boundsArray.indices.contains(5) {
let element = boundsArray[5]
} else {
print("索引超出范围")
}
3. 空数组操作
// 错误示例
let emptyArray: [Int] = []
// let first = emptyArray[0] // 运行时错误
// 正确做法
if let first = emptyArray.first {
print("第一个元素: \(first)")
} else {
print("数组为空")
}
总结
Swift Array 是一个功能强大且类型安全的集合类型,提供了丰富的操作方法和函数式编程特性。通过合理使用这些功能,可以编写出高效、安全、易读的代码。
关键要点:
- 理解数组的基本概念和性能特征
- 掌握各种初始化方法
- 熟练使用数组的增删改查操作
- 学会使用函数式编程方法
- 注意数组的安全性和边界检查
- 遵循最佳实践,避免常见陷阱
Swift 的 Set(集合)是一种无序且不重复的元素集合,常用于去重、集合运算等场景。
1. Set 的声明与初始化
// 声明一个空的 Set
var emptySet = Set<Int>()
// 使用数组字面量初始化 Set(自动去重)
let numberSet: Set = [1, 2, 3, 4, 5, 2, 3] // 结果:[1, 2, 3, 4, 5]
2. 基本操作
var fruits: Set = ["Apple", "Banana", "Orange"]
// 添加元素
fruits.insert("Grape")
// 删除元素
fruits.remove("Banana")
// 判断是否包含某元素
fruits.contains("Apple") // true
// 获取元素个数
fruits.count
// 判断是否为空
fruits.isEmpty
3. 遍历 Set
for fruit in fruits {
print(fruit)
}
4. Set 的常用集合运算
let setA: Set = [1, 2, 3, 4]
let setB: Set = [3, 4, 5, 6]
// 交集
let intersection = setA.intersection(setB) // [3, 4]
// 并集
let union = setA.union(setB) // [1, 2, 3, 4, 5, 6]
// 差集
let subtracting = setA.subtracting(setB) // [1, 2]
// 对称差集(不属于双方的元素)
let symmetricDiff = setA.symmetricDifference(setB) // [1, 2, 5, 6]
5. Set 的比较
let setC: Set = [1, 2]
let setD: Set = [1, 2, 3, 4]
setC.isSubset(of: setD) // true,setC 是 setD 的子集
setD.isSuperset(of: setC) // true,setD 是 setC 的超集
setC == setD // false
6. Set 的常见应用场景
- 数组去重:
let uniqueArray = Array(Set(array))
- 判断两个集合是否有交集:
setA.isDisjoint(with: setB)
7. 注意事项
- Set 元素必须遵循 Hashable 协议(大多数基础类型都已遵循)。
- Set 是无序的,不能通过下标访问元素。