iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
0
Software Development

給我 30 天,給你一輩子:Swift 從零開始系列 第 8

Day 8 | Swift Collection Types 三部曲之首部曲:Array

  • 分享至 

  • xImage
  •  

集合型別 ( Collection Types ):Array

基礎篇的開頭有介紹,Swift 有三個主要的 Collection Types:Array、Set 以及 Dictionary,其中只有 Array 是有順序地排列,其他兩個則不是,而且這三個型都是泛型集合 ( Generic Collection ),所以可以指派任何型別的值,今天首部曲就來介紹 Array。


Array

Initialization

Array 是一個有順序排列的集合資料,你可以用透過 Array<Element> 來註記型別,你也可以使用 [Element] ,然而 Element 必須輸入一個型別:

var 購物清單1: Array<String> = []
var 購物請單2: [String] = []

或是直接使用 [Element]() 作為初始值,這三個的功能都是一樣的喔!

var 購物清單3 = [String]()

print(購物清單1 == 購物清單2) // True
print(購物清單2 == 購物清單3) // True

這邊使用的是一個 String 陣列,只要在中括號裡的每個 String 之間加上 , ,即可指派到購物清單作為初始值。

var 購物清單: [String] = ["陶朱隱園", "藍寶堅尼", "LEGO 75978"]

但是你不能將非 String 的資料放在 String 陣列裡,假使我們在購物清單中加入整數 100,這時候就會跳出 Cannot convert value of type 'Int' to expected element type 'String' 錯誤,Xcode 溫馨小提醒你不能將整數型別的數值放入一個 String 陣列中。

https://ithelp.ithome.com.tw/upload/images/20200908/20118283Fujzycodcl.png

還記得型別推斷嗎?你也可以不用特別註記型別,直接指派初始值,在編譯的時候透過型別推斷,就可以知道型別,在 Array 也是如此喔。

var 購物清單 = ["陶朱隱園", "藍寶堅尼", "LEGO 75978"] // 這是一個 [String] 變數
var 每日溫度表 = [37.1, 35.3, 36.3, 37.2, 32.7] // 這是一個 [Double] 變數

老師,這裏有一個疑問 ><:

如果在沒型別註記的 array 裡,加了一個有著不同型別的值,這時候型別推斷的結果為何?

問得很好 ( 自問自答 ),我們來看下面這個範例:

var anyArray = ["abc", 123, 456.789, true]

如果你在 Playground 上,他會跳出一個錯誤跟你說 Heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional,簡單來說就是他不太確定這個變數到底是什麼,所以這邊就推斷為 Any,你如果真的要使用的話必須在後面加上 as [Any]

Any 可以代表著任何型別,所以在編譯的時候發現該陣列中有著不同型別的數值,就會自動推斷為 [Any] 型別,但這種宣告方式只推薦用於「你很清楚知道這個變數要做什麼」,否則很容易因為型別錯誤早成程式碼中斷,在後面的文章會再來細部探討 Any Type。

到這裡幾乎都是以 [String] 型別作為範例,你也可以試試看其他型別,像是 [Int][Double][Bool]... 等 /images/emoticon/emoticon15.gif

Array Modification

Add Element

根據前面基礎的教學中可以知道,可以修改的前提就是宣告的必須是變數,我們就繼續以上面購物清單為範例,假定今天我們想修改 Array 中的值,有幾個方式

  • ++=:還記得上一章基本運算子提到的,可以使用 += 來達到相同的效果喔。
  • Array.append(element)
var 購物清單 = [String]()
購物清單 = 購物清單 + ["藍寶堅尼"]
// ["藍寶堅尼"]

購物清單.append("LEGO 75978")
// ["藍寶堅尼", "LEGO 75978"]

但是這兩個方式也只能加在 Array 最尾端,但你有一種方式可以讓你加入到 Array 的任意位置中:Array.insert(value, at:)

購物清單.insert("陶朱隱園", at: 1)
// ["藍寶堅尼", "陶朱隱園", "LEGO 75978"]

Remove Element

「既然可以加,那一定可以移除囉!」

「沒錯,確實可以喔 ><」

「那上面使用 += 來新增,移除是不是可以使用 -= 啊?」

「那可不行!」


移除你可以使用最粗暴的移除方法就是直接指派一個新的 Array,但是還是有其他的方式:

  • Array.remove(at:):移除某個特定位置的資料
  • Array.removeFirst():移除陣列第一筆資料
  • Array.removeLast():移除陣列最後一筆資料,效果跟 Array.popLast() 一樣
購物清單.remove(at: 1)
// ["藍寶堅尼", "LEGO 75978"]

購物清單.removeFirst()
// ["LEGO 75978"]

購物清單.removeLast()
// []

如果你是想直接清空整個陣列,可以直接使用指派空陣列的方式,或是 Swift 提供了一個實體方法 Array.removeAll(),可以用來清空整個陣列喔。

冷知識

Array.removeLast()Array.popLast() 還是有點差別喔!可以看到官方 API 描述這兩個 method, removeLast() 以及 popLast(),他們的差異就在於如果要被處理的 Array 是空陣列的話,popLast() 會回傳 nil;removeLast() 則不允許這樣操作,會跳出一個 Fatal Error

Use Array

在上述的說明中只提到要如何新增及修改,但是要怎麼取用呢?

很簡單,只需要使用 Array[index] 的方式就可以取得你想要的值囉,來看下面範例:

var 購物清單 = ["藍寶堅尼", "陶朱隱園", "LEGO 75978", "口罩"]
print(購物清單[0]) // "藍寶堅尼"
print(購物清單[1]) // "陶朱隱園"
print(購物清單[2]) // "LEGO 75978"
print(購物清單[3]) // "口罩"

在 Swift 陣列裡的第一個元素的 index 的為 0,以此類推,所以你就可以針對你想索取的元素,輸入其 index 就可以找到囉,是不是很簡單!

但使用的時候要小心,假定今天我們輸入的 index 值超過了 Array 的大小的話,這時候就會跳出 Fatal error: Index out of range 的錯誤訊息。

print(購物清單[4]) // Fatal error: Index out of range

還記得在字串與字元那篇有提到一個協定 Collection,同樣的 Array 也是實作了 Collection Protocol,所以你也可以使用 for ... in loop,來走訪陣列裡每個元素。

for 購物項目 in 購物清單 {
	print(購物項目)
}

/*
Prints:
藍寶堅尼
陶朱隱園
LEGO 75978
口罩
*/

除了照上述的這個方式走訪之外,也可以用簡單的回圈方式來實作,但是我們總得知道陣列的長度才能去界定範圍吧?

可以從 Array API 發現有一個 count 的屬性,我們可以用 count 來取得陣列的長度。

var 購物清單 = ["藍寶堅尼", "陶朱隱園", "LEGO 75978", "口罩"]
print("要買的東西總共有 \(購物清單.count) 項")
// 要買的東西總共有 4 項

所以我們也可以這麼做,也可以達到走訪的效果喔~

for i in 0..<購物清單.count {
	print(購物清單[i])
}

/*
Prints:
藍寶堅尼
陶朱隱園
LEGO 75978
口罩
*/

Check Array

再來介紹幾個檢查 Array 狀態的屬性及方法~

檢查是否為空陣列

使用 Array.isEmpty 來檢查陣列是否為空陣列。

let emptyArray: Array<String> = []
let nonEmptyArray = ["1"]

print(emptyArray.isEmpty) // true
print(nonEmptyArray.isEmpty) // false

檢查值是否存在於陣列中

使用 Array.contains(element) 來檢查值是否存在於陣列中,這邊的 element 型別必須與 Array 的中的值型別相同,否則會跳出 error: cannot convert value ...

let intArray = [1, 3, 5, 7, 9]
print(intArray.contains(7)) // true
print(intArray.contains(2)) // false
print(intArray.contains("1")) // error: cannot convert value of type 'String' to expected argument type 'Int'

上一篇
Day 7 | Swift 基本運算子
下一篇
Day 9 | Swift Collection Types 三部曲之二部曲:Set
系列文
給我 30 天,給你一輩子:Swift 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言