Swift 陣列 (Arrays)

陣列是用來儲存一系列相同型別的數值。

建立陣列

最簡單的方式是用方括號 []

var shoppingList: [String] = ["Eggs", "Milk"]

// 如果型別可以推斷,可以省略型別標註
var scores = [10, 20, 30] 

建立一個空陣列:

var emptyInts: [Int] = []
// 或
var anotherEmptyInts = [Int]()

存取與修改陣列

取得元素數量 .count

print("清單上有 \(shoppingList.count) 個項目")

檢查是否為空 .isEmpty

if shoppingList.isEmpty {
    print("清單是空的")
}

新增元素 .append

使用 append 方法或 += 運算子:

shoppingList.append("Flour")
shoppingList += ["Baking Powder", "Chocolate Spread"]

存取與修改值

使用索引 (Index) 語法。請記得索引是從 0 開始的

var firstItem = shoppingList[0]
shoppingList[0] = "Six Eggs" // 修改第一個項目

你也可以一次修改一個區間的值:

shoppingList[4...6] = ["Bananas", "Apples"]

插入與移除 .insert .remove

// 在索引 0 的位置插入 "Maple Syrup"
shoppingList.insert("Maple Syrup", at: 0)

// 移除索引 0 的項目
let mapleSyrup = shoppingList.remove(at: 0)

// 移除最後一個項目
let apples = shoppingList.removeLast()

遍歷陣列

使用 for-in 迴圈:

for item in shoppingList {
    print(item)
}

如果你同時需要所以和值,使用 enumerated() 方法:

for (index, value) in shoppingList.enumerated() {
    print("Item \(index + 1): \(value)")
}

常用高階函式 (Higher Order Functions)

Swift 的陣列支援許多強大的高階函式,讓我們能以簡潔的 functional programming 風格處理資料。

關於 $0 的說明: 在 Swift 的閉包 (Closure) 中,我們可以使用 $0, $1, $2 ... 等作為參數的簡寫代名詞。 例如 $0 代表第一個參數 (通常也是遍歷到的那個 array 元素),這樣我們就不需要特別去命名它,讓程式碼更簡潔。

Map 轉換 (.map)

map 用於將陣列中的每一個元素進行轉換,並回傳一個包含轉換後結果的新陣列。

let numbers = [1, 2, 3, 4]
let doubled = numbers.map { $0 * 2 }
// doubled 為 [2, 4, 6, 8]

let numberStrings = numbers.map { "Number \($0)" }
// numberStrings 為 ["Number 1", "Number 2", "Number 3", "Number 4"]

Filter 過濾 (.filter)

filter 根據指定的條件篩選元素,回傳一個包含符合條件元素的新陣列。

let numbers = [1, 2, 3, 4, 5, 6]
let evenNumbers = numbers.filter { $0 % 2 == 0 }
// evenNumbers 為 [2, 4, 6]

Reduce 縮減 (.reduce)

reduce 將陣列中的所有元素合併為一個單一的值。需要提供一個初始值 (Initial Result) 和一個閉包來定義如何合併。

let numbers = [1, 2, 3, 4, 5]
let sum = numbers.reduce(0) { $0 + $1 } 
// 初始值 0,每次將當前結果與下一個元素相加
// sum 為 15

// 也可以簡寫為:
let sumSimplified = numbers.reduce(0, +)

CompactMap 去除 nil 並轉換

compactMap 類似於 map,但它會自動過濾掉轉換結果為 nil 的項目,並對非 nil 的結果進行解包 (Unwrap)。

let strings = ["1", "2", "three", "4", "five"]
let validNumbers = strings.compactMap { Int($0) }
// validNumbers 為 [1, 2, 4]
// "three" 和 "five" 轉換 Int 會變成 nil,所以被忽略

FlatMap 攤平

flatMap 用於將巢狀陣列 (陣列中有陣列) 「攤平」成單一層級的陣列。

let nestedArray = [[1, 2, 3], [4, 5], [6]]
let flattened = nestedArray.flatMap { $0 }
// flattened 為 [1, 2, 3, 4, 5, 6]

排序 (Sorting)

Swift 提供兩種主要的排序方式:sort() (原地排序) 和 sorted() (回傳新陣列)。

sort() 原地排序

直接修改原始陣列的順序。陣列必須是變數 (var)

var numbers = [3, 1, 4, 1, 5]
numbers.sort()
// numbers 變為 [1, 1, 3, 4, 5]

你也可以傳入 closure 自訂排序規則:

// 降序排列 (大到小)
numbers.sort { $0 > $1 } 
// numbers 變為 [5, 4, 3, 1, 1]

sorted() 回傳排序後的新陣列

不修改原始陣列,而是回傳一個新的已排序陣列。適用於常數陣列或不想改變原資料時。

let numbers = [3, 1, 4]
let sortedNumbers = numbers.sorted()
// sortedNumbers 為 [1, 3, 4]
// numbers 仍為 [3, 1, 4]