iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
Software Development

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

Day 9 | Swift Collection Types 三部曲之二部曲:Set

  • 分享至 

  • xImage
  •  

集合型別 ( Collection Types ):Set

上一篇提到了第一格 Collection Type:Array,是一個有順序性的集合,所以你可以使用 index 來檢索你要的資料,但是第二部曲要來介紹的是無順序的集合,Set。


Set 跟 Array 很相似,一樣都只允許存放同型別的資料,但差別就在於 Set 是沒有順序性的,在取用上相對於 Array 就不是這麼容易,所以要使用 Set 的前提,最好確保儲存的資料是不會被頻繁的來取用,否則使用 Array 會是比較適合,接下來我們就來看 Set 的特性及使用方式吧!

Initialization

Set 的宣告方式跟 Array 幾乎是一模一樣,可以用 Set<element> 來宣告一個 Set。

var 套餐A: Set<String> = []
var 套餐B: Set<String> = ["乾麵", "魚丸湯", "燙青菜"]
套餐A = ["乾麵", "魚丸湯"]

print(套餐A) // ["魚丸湯", "乾麵"]
print(套餐B) // ["魚丸湯", "乾麵", "燙青菜"]

兩個但是...

但是 Set 跟 Array 的語法都是以 [] 的方式來實作,所以如果在宣告的時候不特別註記型別直接指派初始值,在型別推論預設會推論為 Array 喔!

var 套餐C = ["炒飯", "貢丸湯"]
print("套餐C 的型別為 \(type(of: 套餐C))")
// 套餐C 的型別為 Array<String>

但是 Set 不能像 Array 一樣直接使用 [element] 來宣告,因為這樣宣告,也會被推論為 Array。

var 套餐D: [String] = ["炒飯", "中杯紅茶"]
print("套餐D 的型別為 \(type(of: 套餐D))")
// 套餐D 的型別為 Array<String>

Set Modification

Add Element

這裡來介紹兩種方式來加入 element 到 Set 中,element 必須與 Set 中的值型態相符:

  • insert(_ newMember: element)
  • update(with newMember: element)

這兩個 methods 都可以加入新的 element 到 Set 裡,但是他們終究還是有些許差別,我們來看看這兩位同學在官方 API 是怎樣被描述的 ( insert(_:)update(with:) ),可以發現到 insert 再加入新的 element 前,會先要檢查是否存在於 Set 中;update 則會無條件的加入,把舊有的 element 取代掉。

var exampleSet: Set = [1, 2, 3]
print(exampleSet.insert(4))
print(exampleSet.insert(4))
print(exampleSet.update(with: 5))
print(exampleSet.update(with: 5))
print(exampleSet)

/* 
Prints:
(inserted: true, memberAfterInsert: 4)
(inserted: false, memberAfterInsert: 4)
nil
Optional(5)
[2, 1, 4, 5, 3]
*/

我是誰?我在哪?

讓我們來一起看看上面發生什麼事情,在這之前我們來回顧一下這兩個方法似乎都有回傳值:

  • insert(_ newMember: element) 這個方法會回傳一組 tuple:(inserted: Bool, memberAfterInsert: Element),當 newMember 不存在於 Set 中,就會加入新的 element,然而inserted 會回傳 truememberAfterInsert 會回傳 newMember;反之則是 false 以及 oldMember,並且不會加入新 element。
  • update(with newMember: element) 這個方法會回傳一個 Optional element,當 newMember 不存在於 Set 中,會回傳 nil;要不然就會回傳一個 Optional(newMember)

Remove Element

如果想要移除 Set 某個 element,可以像是 Array 使用 remove,但是使用的方式有點不太一樣的地方是,Array 在使用 remove 需要帶入 index 值,但是 Set 是一個無序排列,可以 Print 看看你會發現,每一次 Set 的排列都會不一樣,那在 Set 要怎麼使用 remove 呢?來看看 Set 的實體方法:

  • remove(_ member: Element) -> Element?

這個方法需要帶入 Element,然而這個在移除之前,會先檢查 Element 是否存在於 Set 中,如果存在就移除掉,然後回除一個 Optional(element),如果找不到的話就只會回傳 nil,而且既然找不到 element,所以也就沒什麼移不移除的需求了。

var exampleSet: Set = [1, 2, 3]
print(example.remove(1)) // prints Optional(1); exampleSet 現在只剩 [2, 3]
print(example.remove(4)) // prints nil; exampleSet 還是只剩 [2, 3]

Use Set

Set 與 Array 一樣,都實作了 Collection Protocol,所以也可以使用 for...in loop 走訪每個 Element~

let stringSet: Set = ["A", "B", "C", "D"]
for element in StringSet {
	print(element)
}

同理你也可以使用上一篇介紹 contains、isEmpty 以及 count。

最主要來介紹 Set 比較常用的方法,還記得集合之間的關係比較吧,讓我們來回憶一下:

  • 交集
  • 聯集
  • 差集
  • 對稱差集

我們來看個官方的圖就比較清楚一點~

https://ithelp.ithome.com.tw/upload/images/20200909/20118283wRuvIg0aYo.png

所以如果以所以如果以程式碼表示就會像是這樣:

let aSet: Set = [1, 3, 5, 7, 9, 2]
let bSet: Set = [1, 5, 9, 6]

aSet.intersection(bSet).sorted()
// [1, 5, 9]

aSet.union(bSet).sorted()
// [1, 2, 3, 5, 6, 7, 9]

aSet.subtracting(bSet).sorted()
// [2, 3, 7]

aSet.symmetricDifference(bSet).sorted()
// [2, 3, 6, 7]

上一篇
Day 8 | Swift Collection Types 三部曲之首部曲:Array
下一篇
Day 10 | Swift Collection Types 三部曲之終章:Dictionary
系列文
給我 30 天,給你一輩子:Swift 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言