Swift 中 Array 的簡單介紹,方便初學(xué)者快速入門
目錄
- 基礎(chǔ)概念
- 聲明和初始化
- 數(shù)組屬性
- 數(shù)組操作
- 數(shù)組遍歷
- 數(shù)組方法
- 數(shù)組切片
- 多維數(shù)組
- 性能優(yōu)化
- 安全性和錯(cuò)誤處理
- 高級(jí)用法
- 實(shí)際應(yīng)用示例
- 最佳實(shí)踐
- 常見陷阱
基礎(chǔ)概念
Array 是 Swift 中的泛型集合類型,用于存儲(chǔ)有序的元素集合。
特點(diǎn)
- 有序性:元素按照插入順序排列
- 可重復(fù):允許存儲(chǔ)重復(fù)的元素
- 類型安全:編譯時(shí)類型檢查
-
可變性:使用
var聲明可修改,使用let聲明不可修改
性能特征
- 隨機(jī)訪問:O(1) 時(shí)間復(fù)雜度
- 插入/刪除:O(n) 時(shí)間復(fù)雜度(在末尾操作除外)
- 內(nèi)存效率:連續(xù)內(nèi)存存儲(chǔ)
聲明和初始化
基本語法
// 顯式類型聲明
let ints: Array<Int> = [1, 2, 3, 4, 5]
let strings: [String] = ["one", "two", "three"]
// 類型推斷
let numbers = [1, 2, 3, 4, 5] // 自動(dòng)推斷為 [Int]
let words = ["hello", "world"] // 自動(dòng)推斷為 [String]
空數(shù)組初始化
var emptyInts: [Int] = []
var emptyStrings = [String]()
var emptyDoubles = Array<Double>()
重復(fù)元素初始化
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]
數(shù)組屬性
基本屬性
let sampleArray = [1, 2, 3, 4, 5]
print(sampleArray.count) // 5 - 元素個(gè)數(shù)
print(sampleArray.isEmpty) // false - 是否為空
print(sampleArray.capacity) // 當(dāng)前分配的容量
元素訪問
// 安全訪問(返回可選值)
print(sampleArray.first) // Optional(1)
print(sampleArray.last) // Optional(5)
// 強(qiáng)制訪問(需要確保數(shù)組不為空)
print(sampleArray.first!) // 1
print(sampleArray.last!) // 5
// 索引訪問
print(sampleArray[2]) // 3
數(shù)組操作
添加元素
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]
// 刪除第一個(gè)元素
let firstRemoved = deleteArray.removeFirst() // 返回 1
print(deleteArray) // [2, 4, 5, 6]
// 刪除最后一個(gè)元素
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]
數(shù)組遍歷
基本遍歷
let traverseArray = ["apple", "banana", "orange", "grape"]
// for-in 循環(huán)
for item in traverseArray {
print(item)
}
// 帶索引的遍歷
for (index, item) in traverseArray.enumerated() {
print("索引 \(index): \(item)")
}
高級(jí)遍歷
// 使用 indices 遍歷索引
for index in traverseArray.indices {
print("索引 \(index): \(traverseArray[index])")
}
// 使用 stride 遍歷
for index in stride(from: 0, to: traverseArray.count, by: 2) {
print("偶數(shù)索引 \(index): \(traverseArray[index])")
}
// 反向遍歷
for item in traverseArray.reversed() {
print(item)
}
// 帶索引的反向遍歷
for (index, item) in traverseArray.enumerated().reversed() {
print("反向索引 \(index): \(item)")
}
數(shù)組方法
排序
let methodArray = [3, 1, 4, 1, 5, 9, 2, 6]
// 初始排序
var sortArray = methodArray
sortArray.sort() // 升序排序
sortArray.sort(by: <) // 升序排序
sortArray.sort(by: >) // 降序排序
// 返回新數(shù)組的排序
let sortedArray = methodArray.sorted() // 不改變?cè)瓟?shù)組
查找
let searchArray = ["apple", "banana", "orange", "grape"]
// 查找元素是否存在
let containsApple = searchArray.contains("apple") // true
// 查找元素索引
if let index = searchArray.firstIndex(of: "banana") {
print("banana 的索引: \(index)") // 1
}
// 查找滿足條件的第一個(gè)元素
if let firstLong = searchArray.first(where: { $0.count > 5 }) {
print("第一個(gè)長度大于5的元素: \(firstLong)") // "banana"
}
函數(shù)式編程方法
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]
數(shù)組切片
基本切片
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]
多維數(shù)組
二維數(shù)組
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(matrix[0]) // [1, 2, 3]
print(matrix[1][1]) // 5
創(chuàng)建多維數(shù)組
var emptyMatrix = Array(repeating: Array(repeating: 0, count: 3), count: 3)
遍歷多維數(shù)組
for (rowIndex, row) in matrix.enumerated() {
for (colIndex, element) in row.enumerated() {
print("matrix[\(rowIndex)][\(colIndex)] = \(element)")
}
}
性能優(yōu)化
預(yù)分配容量
var optimizedArray = [Int]()
optimizedArray.reserveCapacity(1000) // 預(yù)分配1000個(gè)元素的容量
批量操作
var batchArray = [Int]()
batchArray.reserveCapacity(100)
// 批量添加(比逐個(gè)添加更高效)
batchArray.append(contentsOf: 1...100)
延遲計(jì)算
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]
安全性和錯(cuò)誤處理
邊界檢查
let safeArray = [1, 2, 3, 4, 5]
// 安全的索引訪問
if safeArray.indices.contains(10) {
let element = safeArray[10]
} else {
print("索引超出范圍")
}
可選綁定
if let firstElement = safeArray.first {
print("第一個(gè)元素: \(firstElement)")
}
if let lastElement = safeArray.last {
print("最后一個(gè)元素: \(lastElement)")
}
條件刪除
var conditionalArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// 刪除所有偶數(shù)
conditionalArray.removeAll { $0 % 2 == 0 }
print(conditionalArray) // [1, 3, 5, 7, 9]
高級(jí)用法
數(shù)組比較
let array1 = [1, 2, 3]
let array2 = [1, 2, 3]
let array3 = [1, 2, 4]
print(array1 == array2) // true
print(array1 == array3) // false
數(shù)組連接
let arrayA = [1, 2, 3]
let arrayB = [4, 5, 6]
let combined = arrayA + arrayB // [1, 2, 3, 4, 5, 6]
自定義擴(kuò)展
// 數(shù)組分塊
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]]
// 數(shù)組去重(保持順序)
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]
實(shí)際應(yīng)用示例
學(xué)生成績管理
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 }
// 計(jì)算平均分
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)
]
// 計(jì)算總價(jià)
let totalPrice = cart.map { $0.price * Double($0.quantity) }.reduce(0, +)
// 添加商品
cart.append(Product(name: "葡萄", price: 8.0, quantity: 1))
// 移除特定商品
cart.removeAll { $0.name == "香蕉" }
數(shù)據(jù)分析
let dataPoints = [23, 45, 67, 89, 12, 34, 56, 78, 90, 11]
// 統(tǒng)計(jì)信息
let minValue = dataPoints.min() ?? 0
let maxValue = dataPoints.max() ?? 0
let sumValue = dataPoints.reduce(0, +)
let average = Double(sumValue) / Double(dataPoints.count)
// 數(shù)據(jù)分組
let grouped = Dictionary(grouping: dataPoints) { $0 / 20 }
最佳實(shí)踐
1. 類型安全
- 始終使用明確的類型聲明
- 利用 Swift 的類型推斷功能
2. 性能考慮
- 對(duì)于頻繁修改的數(shù)組,使用
var聲明 - 預(yù)分配容量以提高性能
- 使用批量操作而不是循環(huán)
3. 內(nèi)存管理
- 及時(shí)清理不需要的數(shù)組引用
- 避免循環(huán)引用
4. 錯(cuò)誤處理
- 始終檢查數(shù)組邊界
- 使用可選綁定進(jìn)行安全訪問
5. 代碼可讀性
- 使用有意義的變量名
- 適當(dāng)使用注釋
- 遵循 Swift 編碼規(guī)范
常見陷阱
1. 修改常量數(shù)組
// 錯(cuò)誤示例
let constantArray = [1, 2, 3]
// constantArray.append(4) // 編譯錯(cuò)誤
// 正確做法
var mutableArray = [1, 2, 3]
mutableArray.append(4) // 正確
2. 數(shù)組越界
// 錯(cuò)誤示例
let boundsArray = [1, 2, 3]
// let element = boundsArray[5] // 運(yùn)行時(shí)錯(cuò)誤
// 正確做法
if boundsArray.indices.contains(5) {
let element = boundsArray[5]
} else {
print("索引超出范圍")
}
3. 空數(shù)組操作
// 錯(cuò)誤示例
let emptyArray: [Int] = []
// let first = emptyArray[0] // 運(yùn)行時(shí)錯(cuò)誤
// 正確做法
if let first = emptyArray.first {
print("第一個(gè)元素: \(first)")
} else {
print("數(shù)組為空")
}
總結(jié)
Swift Array 是一個(gè)功能強(qiáng)大且類型安全的集合類型,提供了豐富的操作方法和函數(shù)式編程特性。通過合理使用這些功能,可以編寫出高效、安全、易讀的代碼。
關(guān)鍵要點(diǎn):
- 理解數(shù)組的基本概念和性能特征
- 掌握各種初始化方法
- 熟練使用數(shù)組的增刪改查操作
- 學(xué)會(huì)使用函數(shù)式編程方法
- 注意數(shù)組的安全性和邊界檢查
- 遵循最佳實(shí)踐,避免常見陷阱
Swift 的 Set(集合)是一種無序且不重復(fù)的元素集合,常用于去重、集合運(yùn)算等場景。
1. Set 的聲明與初始化
// 聲明一個(gè)空的 Set
var emptySet = Set<Int>()
// 使用數(shù)組字面量初始化 Set(自動(dòng)去重)
let numberSet: Set = [1, 2, 3, 4, 5, 2, 3] // 結(jié)果:[1, 2, 3, 4, 5]
2. 基本操作
var fruits: Set = ["Apple", "Banana", "Orange"]
// 添加元素
fruits.insert("Grape")
// 刪除元素
fruits.remove("Banana")
// 判斷是否包含某元素
fruits.contains("Apple") // true
// 獲取元素個(gè)數(shù)
fruits.count
// 判斷是否為空
fruits.isEmpty
3. 遍歷 Set
for fruit in fruits {
print(fruit)
}
4. Set 的常用集合運(yùn)算
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]
// 對(duì)稱差集(不屬于雙方的元素)
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 的常見應(yīng)用場景
- 數(shù)組去重:
let uniqueArray = Array(Set(array)) - 判斷兩個(gè)集合是否有交集:
setA.isDisjoint(with: setB)
7. 注意事項(xiàng)
- Set 元素必須遵循 Hashable 協(xié)議(大多數(shù)基礎(chǔ)類型都已遵循)。
- Set 是無序的,不能通過下標(biāo)訪問元素。