iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
Mobile Development

從零開始的8-bit迷宮探險!Swift SpriteKit 遊戲開發實戰系列 第 4

從零開始的8-bit迷宮探險【Level 4】Swift 基礎語法 (二)

今日目標

  • 認識完變數、常數、型態之後,接著來認識將資料做集合處理的型別:
    • 陣列 (Array)
    • 字典 (Dictionary)
    • 集合 (Set)
  • 將針對不同型別,介紹幾種較常使用的操作

陣列 (Array)

陣列是有序列的集合,集合內的元素必須是同一種類型的。

  • 宣告陣列的方法:可以在宣告時加上型態,也可以讓 swift 自己偵測型態
var arrayNumber = [1, 2, 5, 10]
var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
  • 修改陣列中的元素
    附註:陣列第一個元素的 index 是從 0 開始
var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
arrayString[2] = "MoMo"
print(arrayString)
印出結果:
["Kevin", "Yoyo", "MoMo", "Sam"]
  • 加入新元素,使用 append
var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
arrayString.append("MoMo")
print(arrayString)
印出結果:
["Kevin", "Yoyo", "Stan", "Sam", "MoMo"]
  • 移除元素,使用 remove
var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
arrayString.remove(at: 1)
print(arrayString)
印出結果:
["Kevin", "Stan", "Sam"]
  • 計算陣列的長度,使用 count
var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
print(arrayString.count)
印出結果:
4
  • 遍歷陣列中的元素

1. 使用 forEach

var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
arrayString.forEach { item in
    print(item)
}
印出結果:
Kevin
Yoyo
Stan
Sam

2. 使用 for-in

var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
for item in arrayString {
    print(item)
}
印出結果:
Kevin
Yoyo
Stan
Sam

如果想取得該元素在陣列中的 index,可以使用 enumerated(),它會回傳 index 及該元素的序列資料。
我們分別在 forEach 及 for-in 中使用 enumerated():

var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
arrayString.enumerated().forEach { index, item in
    print("[forEach] \(index): \(item)")
}
for (index, item) in arrayString.enumerated() {
    print("[for loop] \(index): \(item)")
}
印出結果:
[forEach] 0: Kevin
[forEach] 1: Yoyo
[forEach] 2: Stan
[forEach] 3: Sam
[for loop] 0: Kevin
[for loop] 1: Yoyo
[for loop] 2: Stan
[for loop] 3: Sam
  • 陣列的排序

1. sort()

  • 直接使用 sort(),會由小到大排序:
var arrayNumber = [1, 2, 5, 10, 3, 9]
arrayNumber.sort()
print(arrayNumber)
印出結果:
[1, 2, 3, 5, 9, 10]

2. 自訂排序方式

  • 如果想自訂排序的方式,可以用以下方式:
var arrayNumber = [1, 2, 5, 10, 3, 9]
arrayNumber.sort{ a, b in
    a > b
}
print(arrayNumber)
印出結果:
[10, 9, 5, 3, 2, 1]
  • 此外,swift 提供了更簡便的寫法:$0$1分別代表第一個參數及第二個參數,我們用以下寫法可以達到同樣的效果:
var arrayNumber = [1, 2, 5, 10, 3, 9]
arrayNumber.sort{ $0 > $1 }
print(arrayNumber)
印出結果:
[10, 9, 5, 3, 2, 1]
  • 使用 sort(by:)
    可以直接帶入 >< 符號排序,例如帶入 >,可以由大到小排序:
var arrayNumber = [1, 2, 5, 10, 3, 9]
arrayNumber.sort(by: >)
print(arrayNumber)
印出結果:
[10, 9, 5, 3, 2, 1]
  • 隨機取得陣列中的元素:randomElement()
var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
print(arrayString.randomElement())
印出結果:
Optional("Yoyo")

由於 randomElement() 回傳的資料型態是 Optional,如果想強制取值,可以加上!
關於 Optional 會在之後詳細介紹。

var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
print(arrayString.randomElement()!)
印出結果:
Yoyo
  • 過濾陣列中的元素:filter
    例如過濾出大於等於 5 的數字:
var arrayNumber = [1, 2, 5, 10, 3, 9]
print(arrayNumber.filter{$0 >= 5})
印出結果:
[5, 10, 9]
  • 陣列元素的Mapping:map
    將陣列中的元素,依序依照給定的方式做處理
    例如將每個元素都加上額外的字串:
var arrayString: [String] = ["Kevin", "Yoyo", "Stan", "Sam"]
print(arrayString.map{"My name is \($0)"})
印出結果:
["My name is Kevin", "My name is Yoyo", "My name is Stan", "My name is Sam"]

字典 (Dictionary)

字典的內容是 key-value 的集合,可以透過 key來取得對應的值。

  • 宣告字典的方法:可以在宣告時加上型態,也可以讓 swift 自己偵測型態
    例如:[Int : String],代表 key 的型態為 Int,值的型態為 String。
var dicNumber = ["good": 80, "excellent": 95, "pass": 60]
var dicString: [String : String] = ["name": "Yoyo", "age": "18", "hobby": "hiking"]
  • 修改字典中的值
    透過 key 來改變對應的值
var dicString: [String : String] = ["name": "Yoyo", "age": "18", "hobby": "hiking"]
dicString["age"] = "10"
print(dicString)
印出結果:
["name": "Yoyo", "age": "10", "hobby": "hiking"]
  • 加入新元素
var dicString: [String : String] = ["name": "Yoyo", "age": "18", "hobby": "hiking"]
dicString["gender"] = "female"
print(dicString)
印出結果:
["hobby": "hiking", "age": "18", "name": "Yoyo", "gender": "female"]
  • 移除元素,使用 removeValue
var dicString: [String : String] = ["name": "Yoyo", "age": "18", "hobby": "hiking"]
dicString.removeValue(forKey: "age")
print(dicString)
印出結果:
["name": "Yoyo", "hobby": "hiking"]
  • 計算字典的長度,使用 count
var dicString: [String : String] = ["name": "Yoyo", "age": "18", "hobby": "hiking"]
print(dicString.count)
印出結果:
3
  • 遍歷陣列中的元素

1. 使用 forEach
可以使用 .key.value 來分別取得 key 及值

var dicString: [String : String] = ["name": "Yoyo", "age": "18", "hobby": "hiking"]
dicString.forEach { item in
    print(item)
    print(item.key)
    print(item.value)
}
印出結果:
(key: "name", value: "Yoyo")
name
Yoyo
(key: "age", value: "18")
age
18
(key: "hobby", value: "hiking")
hobby
hiking

2. 使用 for-in

var dicString: [String : String] = ["name": "Yoyo", "age": "18", "hobby": "hiking"]
for item in dicString {
    print(item)
    print(item.key)
    print(item.value)
}
印出結果:
(key: "name", value: "Yoyo")
name
Yoyo
(key: "age", value: "18")
age
18
(key: "hobby", value: "hiking")
hobby
hiking
  • 隨機取得字典中的元素:randomElement()
var dicString: [String : String] = ["name": "Yoyo", "age": "18", "hobby": "hiking"]
print(dicString.randomElement())
print(dicString.randomElement()!)
印出結果:
Optional((key: "age", value: "18"))
(key: "age", value: "18")
  • 過濾字典中的元素:filter
    例如過濾出值大於等於 80 的元素:
var dicNumber = ["good": 80, "excellent": 95, "pass": 60]
print(dicNumber.filter{$0.value >= 80})
印出結果:
["excellent": 95, "good": 80]
  • 字典元素的Mapping:mapValues
    將字典中的元素,依照給定的方式做處理
    例如將每個元素的值都加 5:
var dicNumber = ["good": 80, "excellent": 95, "pass": 60]
print(dicNumber.mapValues{$0 + 5})
印出結果:
["good": 85, "excellent": 100, "pass": 65]

集合 (Set)

Set 是沒有序列的集合,包含的值都是不重複的

  • 宣告集合的方法:可以在宣告時加上型態,也可以讓 swift 自己偵測型態
var setNumber: Set = [0, 2, 5, 3]
var setString: Set<String> = ["orange", "yellow", "black"]
  • 加入新元素,使用 insert
var setString: Set<String> = ["orange", "yellow", "black"]
setString.insert("white")
print(setString)
印出結果:
["white", "orange", "yellow", "black"]
  • 移除元素,使用 remove
var setString: Set<String> = ["orange", "yellow", "black"]
setString.remove("orange")
print(setString)
印出結果:
["yellow", "black"]
  • 計算集合的長度,使用 count
var setString: Set<String> = ["orange", "yellow", "black"]
print(setString.count)
印出結果:
3
  • 遍歷集合中的元素

1. 使用 forEach

var setString: Set<String> = ["orange", "yellow", "black"]
setString.forEach { item in
    print(item)
}
印出結果:
orange
yellow
black

2. 使用 for-in

var setString: Set<String> = ["orange", "yellow", "black"]
for item in setString {
    print(item)
}
印出結果:
orange
yellow
black
  • 隨機取得集合中的元素:randomElement()
var setString: Set<String> = ["orange", "yellow", "black"]
print(setString.randomElement())
print(setString.randomElement()!)
印出結果:
Optional("black")
black
  • 過濾集合中的元素:filter
    例如過濾出值大於 2 的元素:
var setNumber: Set = [0, 2, 5, 3]
print(setNumber.filter{$0 > 2})
印出結果:
[3, 5]
  • 集合元素的Mapping:map
    將集合中的元素,依照給定的方式做處理
    例如將每個元素的值都乘以 10:
var setNumber: Set = [0, 2, 5, 3]
print(setNumber.map{$0 * 10})
印出結果:
[0, 20, 50, 30]
  • 集合中是否包含某項目:contains
var setString: Set<String> = ["orange", "yellow", "black"]
print(setString.contains("yellow"))
print(setString.contains("red"))
印出結果:
true
false
  • Set 可以做數學的集合運算:
  1. 取得不同集合的交集:intersection
var setString: Set<String> = ["orange", "yellow", "black"]
var setString2: Set<String> = ["red", "yellow", "white"]
print(setString.intersection(setString2))
印出結果:
["yellow"]
  1. 取得不同集合之間,不在對方集合中的元素:symmetricDifference
var setString: Set<String> = ["orange", "yellow", "black"]
var setString2: Set<String> = ["red", "yellow", "white"]
print(setString.symmetricDifference(setString2))
印出結果:
["red", "black", "orange", "white"]
  1. 取得不同集合之間的聯集:union
var setString: Set<String> = ["orange", "yellow", "black"]
var setString2: Set<String> = ["red", "yellow", "white"]
print(setString.union(setString2))
印出結果:
["black", "orange", "yellow", "red", "white"]
  1. 取得不同集合之間的差集:subtracting
    例如:
    • 取得在 setString 中,且不包含在 setString2 中的值
    • 取得在 setString2 中,且不包含在 setString 中的值
var setString: Set<String> = ["orange", "yellow", "black"]
var setString2: Set<String> = ["red", "yellow", "white"]
print(setString.subtracting(setString2))
print(setString2.subtracting(setString))
印出結果:
["black", "orange"]
["red", "white"]

今日小結:
今天認識了不同種類的集合類型,我們可以善用他們不同的特性,選擇適合的類型來使用。
如果需要處理的是有排序的資料,較適合使用陣列 (Array)。
如果要處理的資料不在乎排序,需要 key-value 配對資料,較適合使用字典 (Dictionary)。
若是要處理數學集合運算,則集合 (Set) 是個不錯的選擇。


參考來源:
Array
Dictionary
Set


上一篇
從零開始的8-bit迷宮探險【Level 3】Swift 基礎語法 (一)
下一篇
從零開始的8-bit迷宮探險【Level 5】Swift 基礎語法 (三)
系列文
從零開始的8-bit迷宮探險!Swift SpriteKit 遊戲開發實戰30

尚未有邦友留言

立即登入留言