iT邦幫忙

2021 iThome 鐵人賽

DAY 2
0

前言

我記得我之前在Medium寫文的時候,剛開始提到的就是「藥與盒子」的概念。所謂的藥就是被指派的值,而盒子就是外面宣告的變數或常數。而關於「藥與盒子」的概念,其實也就是一種比喻而已,希望透過這個比喻能讓自己再重複的理解程式語言的運作過程中,是有思考脈絡可循的。但其實把要裝在盒子裡是一個還不錯概念,用以描述程式語言對“值”的存在的探討。

基本資料儲存

有值

在「有值」的這個範疇,我們會有兩種類型的儲存方式,也就是所謂的Constant、Variable,這兩者的區別其實非常直觀,就是經過宣告後:一個是不可變的,一個是可變的

常數(let...)

常數具有不可變性
let box = "Medicine"

變數(var...)

變數具有可變性
var box = "Medicine"

Optional(介於有值與沒有值之間)

通常大家也許不會在第一章的型態的時候提到所謂的Optional可選的問題,但我想既然大家都知道所謂的有值有兩種方式可以呈現,所以相反的,我們也會面對到一個問題是「到底有沒有值?」,於是介於有與無之間的描述,在Swift程式語言中,便會以“?”這個符號去詮釋介於有與無(nil)之間的曖昧狀態。

如果在上一個部分,我們是以box作為詮釋,那Optional的描述會是下面這個樣子:

let box = String?

或是

var box = String?

Anyway,其實這也只是描述值的存在與否的表現方式。

而optional作為介於有值或沒有值(nil)之間的資料儲存型態,最後在運作程式的時候,我們就必須去解決它到底有或者是沒有的問題,但這一部分比較複雜些,日後我們再談。

複雜資料儲存型態

除了基本的資料儲存型態,Swift還提供了我們處理其他種類的資料儲存方式,如:陣列(Array)、集合(Set)、元組(Tuple)、字典(Dictionary)。這四種類別的資料儲存型態各有千秋,也視不同的情景去使用它們。

陣列

陣列Array的邏輯:「以整數值index來存取內容,索引值從0到-1(也就是從第一項到最後一項)」

我不知道「查找」這個詞適不適合來描述你想使用陣列裡的東西時,但這樣理解也許比較直觀一點。

let name = ["MJ","Minny","Austin"]
let value = name[0] //value = "MJ"

接下來介紹一下陣列的基本用法:

  1. 索引值
    這個時候,就大概可以知道陣列在運作的時候,是可以藉由「索引值」去抓出自己到底想要「哪個位置的值」
    而程式語言的索引值基本上是這樣計算的:0代表著第一項,然後第二是1、第三項就2,往後的依此類推……
    不過,陣列的索引值也可以從陣列的尾巴開始算過來,只不過這個時候要由-1開始索引,就會得到陣列的最後一個值,而如果要倒數第二位的話,就是-2…..依此類推

  2. 計算小工具:count
    假若你需要計算陣列裡面有多少個東西的話,也可以用count這個函式去處理,可以很快的得到你要的數量資訊,
    如下:

let names = ["MJ","Minny","Austin"]
let count = names.count //count = 3

  1. 取代原先的內容:變數[索引值]
    如果要取代陣列裡面的某個內容,像我下面要更改「MJ」好了,我想把它改成Julia,這個時候我就把:變數[索引值]這個地方直接填入我需要的索引值,再帶入我要的內容,就會取代了原先的資料。

  2. 陣列新增資料:新增(append)、插入值(insert)
    陣列還有其他的功能,如新增(append)、插入資料(insert),如果是要在陣列的內容裡新增資料的話,就用append這個方式,如下所示:
    如果是要在某個地方「插入」資料的話,那除了要標明要插入的資料,也要標明「要插入的位址」,在下面可以發現,插入的位置要用「at:位址」讓Swift明白你接下來要把資料放在哪裡。

var name = ["MJ","Minny","Austin"]
names.append("JE")
names.insert("Sam",at:1)
//names = ["MJ","Sam","Minny","Austin"]
  1. 刪除陣列裡面的值
    假若你要刪除陣列裡面的值,可以用remove這個函式來做這件事情,但跟上面的insert很像,你必須知道自己要刪除值的位置。
    而假若你要清空陣列裡所有的內容,那使用removeall()這個函數可以很輕鬆的替你做到這件事情。

集合

集合跟陣列、字典的不同在於集合就是一個涵括所有內容的概念,集合像一個袋子,他把所有的東西裝在一起,
但不會跟你講說你要第幾個項目,我拿給你相應的項目(陣列的概念)
or 你跟我講我關鍵字,我把對應的東西拿給你(字典的概念)
,你只能問他,這裡面有沒有A這個東西,他回答有或是沒有(集合的概念)
了解它的運作模式,就會知道,集合這個概念就是「從一個袋子裡面拿出東西」。

var name:Set = ["MJ","Sam","Minny","Austin","JE"]
names.contains("MJ")

//return true

它跟陣列不一樣的地方,在於它沒有排序性、沒有索引性、不可以有重複項,你只能問它:「存在或不存在?」

不過,集合這個東西同樣有所謂的「新增值」與「刪除值」的方式:

var name:Set = ["MJ","Sam","Minny","Austin","JE"]
names.insert("Sneakers")

//name = ["MJ","Sam","Minny","Sneakers","Austin","JE"]

上面三個都不一樣,也就說明了集合的特性。

刪除remove

假若你要刪除全部,則可以用names = []的方式進行

var name:Set = "MJ","Sam","Minny","Austin","JE"
name = []

不過,集合這種資料儲存方式,還有其他的東西可以探討,比如像是高中數學曾經在某堂課提到的「集合運算」,也就是所謂的:交集、聯集、對稱差集、差集

  1. 交集(intersects):取兩個集合的共通處
  2. 差集(exclusive):取兩個集合共通處之外的部分
  3. 聯集(union):兩個集合交集與差集的部分
  4. 對稱差集(substract):取兩個集合其中一集合的差集
    總而言之,這四個集合運算的方式,我們在下面以一些小案例作為解釋:
    假若以下面這幾個集合為基本案例
var number:Set = [1,2,3,4,5,6,7,8,9,10] //1-10的集合
var odd_number:Set = [1,3,5,7,9] //基數集合
var even_number:Set = [2,4,6,8,10] //偶數集合
var prime_number:Set = [2,3,5,7,9] //質數集合
  1. 交集(intersects)
    取兩個集合的共通處
odd_number.interaction(even_number)
//[]空集合
  1. 差集(exclusive)
    取兩個集合共通處之外的部分
odd_number.symmetricDifference(prime_number)`
//[1,2,9,11]
  1. 聯集(union)
    兩個集合交集與差集的部分
odd_number.union(even_number)`
//1-10的集合
  1. 對稱差集(substract):取兩個集合其中一集合的差集
number.substract(even_number)
//[2,4,6,8,10]

綜合言之,集合這個概念從一開始就是「無序」、「不可索引的」、「不可以有重複項」,它跟陣列有很大的差別。但它可以進行所謂的集合運算,這應該算是它的優勢。所以之後要資料儲存的時候。要記得選擇適合的方式儲存哦!

元組

引述 100 Day of Swift 對於元組概念的解析:

Both tuples and arrays allow us to hold several values in one variable, but tuples hold a fixed set of things that can’t be changed, whereas variable arrays can have items added to them indefinitely.

元組的概念是:“內容是不可變的,這是它跟陣列不相同之處。”
瞭解完元組的特性之後,我們可以在下面這裡知道,元組的表達方式是()小括弧:

var game = (name:"Hades",year:"2020")
game.name
game.year

game.0
game.1

然後如果要呼叫元組內的資料的話,可以直接指名參數,它就會對應內容出來,或者也可以以項目排序索引:

所以經上述的描繪,陣列、集合、元組三者可以放在一起做一些小比較:
arrays keep the order(有序) and can have duplicates(重複項),
sets are unordered(無序的) and can’t have duplicates(重複項),
tuples have fixed values(固定值) of fixed types(固定型別) inside them.
稍微簡述一下陣列、集合、元組三者的區別,可大致有下面的分類

  1. 陣列:有序、可目錄索引、可以有重複項
  2. 集合:無序、不可目錄索引,但可以詢問「存在或不存在」、不可重複
  3. 元組:固定值與固定型別、可目錄索引

字典

字典最大的特徵,就是有鍵值對(key-value),這件事情是前三個資料儲存方式都沒有的,而依靠鍵值對的優勢,字典可以很快的透過鍵,來找到值:

var church:[String:String] = ["MJ:HLL","Minny":"Yumen","Austin":"Yumen",]
church["MJ"] //返回HLL
let removeValue = church.removevalue(forKey:"MJ")
//結果會是["Minny":"Yumen","Austin":"Yumen"]

church[:]//刪除全部的鍵值對

如上述,字典在宣告型別的時候,會有兩個型別,一個分別是鍵,一個是值,表達的方式就如這樣:[type:type],因此也就表明了該變數裡面的內容會是這樣的形式,無論你宣告它裡面的型別是什麼。

由鍵取值
而假若你要取用值的話,那可以用變數[key]的這個方式去找到你的值。

刪除資料
刪除特定資料可以用removevalue(forKey: ) 這個函式來做
如果要刪除所有東西,就以變數[:]就可以達到全部都刪除,這樣的動作。

字典與默認值
字典還有個比較特殊的功能,就是當我們可能在字典裡面查找東西的時候,出現nil的情況,也就是說,我的鍵可能對不到值,這時候就可以用default(默認)的方式來進行調整,而不是讓它的內容回傳nil(沒有值)

var grade = [
"chinese",
"English",
"History"
]

let geography = grade["geography",default:0]

綜合上述,字典的特徵就是可以用鍵值對操作資料。
以下再次的複習資料儲存方式的特色:

  1. 陣列:有序、可索引、可有重複項目
  2. 集合:無序、不可索引,但可詢問存在或不存在、無重複項目
  3. 元組:經宣告為元組後,不可改變值與型別
  4. 字典:有鍵值對可以搜尋資料,可透過鍵(key)搜尋值(value)
tags: 鐵人賽

上一篇
#Day1--開始之前
下一篇
# Day3--向左走?向右走?再走一次?那些替你做決定的小事
系列文
Swift30天:從語法到觀念,告訴你在踏入實作前最好弄清楚的那些事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言