Swift_數(shù)據(jù)類型_Array/Set

Swift 中 Array 的簡單介紹,方便初學(xué)者快速入門

目錄

  1. 基礎(chǔ)概念
  2. 聲明和初始化
  3. 數(shù)組屬性
  4. 數(shù)組操作
  5. 數(shù)組遍歷
  6. 數(shù)組方法
  7. 數(shù)組切片
  8. 多維數(shù)組
  9. 性能優(yōu)化
  10. 安全性和錯(cuò)誤處理
  11. 高級(jí)用法
  12. 實(shí)際應(yīng)用示例
  13. 最佳實(shí)踐
  14. 常見陷阱

基礎(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)訪問元素。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容