Swift 初學者 ( 12/12 ) 集合

簡介

這是一個Swift語言教程,基于最新的iOS 9,Xcode 7.3和Swift 2.2,會為你介紹Swift編程非常基礎(chǔ)的內(nèi)容。從電腦如何工作的全程基本原理到語言結(jié)構(gòu),你會足夠了解這門語言,來處理數(shù)據(jù)和管理代碼的行為。

快速鏈接


集合

集合(set)是沒有順序的相同類型唯一值的集合。當你想確保一個項目不會在集合里出現(xiàn)多次的時候,它會變得非常有用,并且項目的順序并不重要。

例如,你想追蹤游戲里還有哪些選手是活躍的,就可以用集合。

你對于這里選手的順序并不感興趣;你想讓集合做的事是存儲人并且并不允許他們在集合里出現(xiàn)兩次。然后只需要問集合,“Alice 還在游戲里嗎?”然后預期得到一個布爾型的 true / false。

如上圖所示,沒有索引或鍵可以用來取回值。你會在這篇文章里讀到,你仍然可以遍歷集合以及查詢特定的值在不在集合里。

創(chuàng)建集合

你可以顯示聲明集合,通過寫 Set 緊接著尖括號里加上類型:

let setOne: Set<Int>

Swift 也能從初始化的類型里推斷集合的類型:

let setTwo = Set<Int>()

打印 setTwo,你會發(fā)現(xiàn)有趣的東西:

print(setTwo)
// > []

它顯示了空的集合字面值和空數(shù)組的相同。

集合字面值

數(shù)組和集合不只是空的字面值相同。事實上,集合沒有自己的字面值,用數(shù)組字面值來創(chuàng)建帶有初始值的集合。看這個例子:

let someArray = [1, 2, 3, 1]

這是一個數(shù)組。那怎么用數(shù)組字面值創(chuàng)建集合呢?像這樣:

let someSet: Set<Int> = [1, 2, 3, 1]

你需要顯示聲明變量為一個 Set。但是,感謝 Swift 的類型推斷,你可以忽略集合包含的值類型:

let anotherSet: Set = [1, 2, 3, 1]

很明顯,這是整數(shù)集合,所以不需要定義集合的類型。

要用行動看一下集合最重要的特色,讓我們打印一下你剛剛創(chuàng)建的集合:

print(someSet)
// > [2, 3, 1]

首先,可以看到?jīng)]有特定的順序。其次,盡管你創(chuàng)建的集合帶有兩個實例值為 1,但這個值只出現(xiàn)了一次——記住,集合的值必須是唯一的。

訪問元素

集合里的元素沒有索引或鍵,所以你怎么知道集合到底有沒有元素呢,以及怎么訪問它擁有的任意元素?就像數(shù)組和字典,集合支持 count 和 isEmpty properties。

print(someSet.isEmpty)
// > false
print(someSet.count)
// > 3

可以使用 contains(_:) 來檢查特定元素是否存在:

print(someSet.contains(1))
// > true
print(someSet.contains(4))
// > false

你也可以使用 first 和 last properties,返回集合里的一個元素。但是,因為集合沒有順序,你無法確切知道會獲得哪個項目。盡管對于尺寸為 0 或 1 的集合,這會是一個獲取單一集合元素的快捷方式。

print(someSet.first)
// > Optional(2)

就像預料的,frist 返回了可選值。它必須這樣做因為集合可能是空的,在這種情況下 property 會返回 nil。

添加和移除元素

回到紙牌游戲。你想為明天規(guī)劃一個游戲,希望選擇一個對所有人對方便的時間。從建議你自己的適宜時間開始:

var myTimes: Set = ["8am", "9am", "10am"]

你把這個集合聲明為變量,因為偏好可能會改變。例如,假設(shè)你決定上午 11 點也是開始游戲的耗時間,那就給集合添加另一個元素:

myTimes.insert("11am")
print(myTimes)
// > ["9am", "8am", "11am", "10am"]

insert(_:) 添加了元素到集合;如果元素已經(jīng)存在,方法什么都不會做。

你意識到上午 8 點太早了。你可以像這樣從集合里移除元素:

let removedElement = myTimes.remove("8am")
print(removedElement)
// > Optional("8am")

remove(_:) 返回被移除的元素,如果它在集合里的話,否則就是 nil。

迷你練習

寫一個函數(shù)移除整數(shù)數(shù)組里的所有重復。數(shù)組?你想問這篇不是關(guān)于集合的嗎?

小提示:數(shù)組有一個用 Set 類型的初始化,集合有一個用 Array 類型的初始化。

遍歷集合

當你想遍歷集合的元素的時候用 for-in 循環(huán):

for element in myTimes {
    print(element)
}
// > 9am
// > 11am
// > 10am

可以預料,結(jié)果沒有預先設(shè)置的順序。然而,這和你在其它集合類型里看到的 for-in 語法相似。

集合操作

集合最強大的特色之一就是他們支持集合操作(set operations),允許你把兩個集合組成一個,創(chuàng)建只有兩個或更多集合的共同值的集合。讓我們用你的偏好時間集合來檢測這些操作,以及另一組時間。

提醒一下,你提議了游戲時間為上午 9 點,10 點或 11 點。Adam 給你發(fā)送了他的偏好時間:

let adamTimes: Set = ["9am", "11am", "1pm"]

讓我們依次看看集合操作的四個類型。

Union

union(_:) 創(chuàng)建新集合,帶有兩個集合所有的值:

let unionSet = myTimes.union(adamTimes)
print(unionSet)
// > ["9am", "11am", "10am", "1pm"]

主要要注意盡管你和 Adam 都選擇了上午 9 點 和 上午 11 點為見面好時間,這些值在新集合只出現(xiàn)了一次。

這里,你留下了你和 Adam 提議的每個時間。

Intersect

intersect(_:) 創(chuàng)建新集合,只帶有兩個集合的共同值。你可以用它創(chuàng)建基于你和 Adam 同意的時間集合。

let intersectSet = myTimes.intersect(adamTimes)
print(intersectSet)
// > ["9am", "11am"]

這里,結(jié)果集合里的值就是在 myTimes 和 adamTimes 集合里同時出現(xiàn)的那些。

Subtract

subtract(_:) 創(chuàng)建新集合,移除在第二個集合里出現(xiàn)的值。

let subtractSet = myTimes.subtract(adamTimes)
print(subtractSet)
// > ["10am"]

從 myTimes 里的所有時間開始。然后 subtract(:_) 移除了 adamTimes 里出現(xiàn)的所有時間,留下只有你提議、Adam 沒有提議的時間。

這個例子里,上午 10 點是唯一的你提議但沒有被 Adam 也提議的時間。

Exclusive Or

exclusiveOr(_:) 創(chuàng)建新集合,帶有只在一個集合出現(xiàn)的值,不包括同時具有的。

let exclusiveOrSet = myTimes.exclusiveOr(adamTimes)
print(exclusiveOrSet)
// > ["10am", "1pm"]

這些是你提議但 Adam 沒有提議的開始時間,以及 Adam 提議而你沒有的開始時間。

迷你練習

快速回答:你會用哪個集合操作來找到見面的合適時間?

集合操作的運行時間

集合和字典有非常相似的實現(xiàn),他們也需要元素可以被哈希。所有操作的運行時間都和字典的那些相同。

關(guān)鍵點

  • 集合(Sets)是相同類型的唯一值的無序集合。
  • 集合在你需要知道一些東西是不是被包含在集合里的時候最有用處。
  • 可以從數(shù)組初始化集合,反之亦然。
  • 集合操作(Set operations)很強力,允許你處理潛在的大量數(shù)據(jù)來組合和過濾元素。

接下來去哪兒?

既然你現(xiàn)在已經(jīng)學習了 Swift 里的三種集合類型,你應(yīng)該很了解他們能做什么以及何時該使用它們。你在繼續(xù)讀教程的時候會看到出現(xiàn)。

現(xiàn)在你知道怎么把數(shù)組組合進數(shù)組、字典和集合里了,本教程的下一個部分涉及了命名類型(named types)。他們允許你同時組合數(shù)據(jù)和代碼到一起,放到自定義的類型里,作為更大和更好的東西的建筑塊!

移步之前,看看下面的挑戰(zhàn)來測試你的集合知識。

挑戰(zhàn)

挑戰(zhàn) A:你就是編譯器

下列哪個為有效語句?

1. let set1: Set<Int> = [1]
2. let set2 = [1]
3. let set3 = Set<Int>()

對于接下來的三條語句,使用這個集合:

let set4: Set = [1, 2, 3]

4. set4[1]
5. set4.insert(1)
6. set4.contains(1)

對于接下來的兩條語句,使用這個集合:

var set5: Set = [1, 2, 3]

7. set5.insert("1")
8. set5.remove(1)

挑戰(zhàn) B:檢測集合包含的項目

假設(shè)你有 10,000 個人的郵箱地址集合:let emails: Set<String>。寫一個函數(shù),如果給定的郵箱地址在集合里就返回 true,否則 false。不允許用 contains(_:) 或遍歷集合。

挑戰(zhàn) C:追蹤到場人數(shù)

你是 Swift 大學里的教授,在教一個為期三天的課程。每天,你追蹤到場人數(shù),通過到場的每個學生的名字到新的集合里。

例如:

let day1: Set = ["Anna", "Benny", "Charlie"]
let day2: Set = ["Anna", "Benny", "Danny"]
let day3: Set = ["Anna", "Danny", "Eric"]
  1. 寫一個函數(shù),返回三天都到了的學生的集合。
  2. 寫一個函數(shù)判斷誰在課程的第一天之后退出了。

這兩個函數(shù)的結(jié)構(gòu)為:

func funcName(day1: Set<String>, day2: Set<String>, day3: Set<String>) ->Set<String>

挑戰(zhàn)和迷你練習源代碼

https://yunpan.cn/cMQMgQ3itt7fy (提取碼:6680)


介紹

歡迎來到Swift世界!Swift是一門蘋果在2014年夏天發(fā)布的編程語言。從那之后,Swift發(fā)布了一個主要的版本跳躍,成為了開始在蘋果平臺:iOS,OS X,watchOS和tvOS開發(fā)的最簡單的方式。

誰適合這篇教程

這篇教程適合懂一點編程、并且希望學習Swift的人。也許你已經(jīng)為網(wǎng)站寫過一些JavaScript代碼,或者用Python寫過一些簡短的程序。這篇教程就是為你準備的!你會學習到編程的基本概念,同時也會成為Swift語言小能手。

如果你是赤裸裸的編程新手,這篇教程也是為你準備的!教程里貫穿有簡短的鍛煉和挑戰(zhàn)來給你一些編程練習,同時測試你的知識。

需要準備什么

要看這篇教程,你需要準備如下的東西:

  • 一臺運行OS X El Captian(10.11)的Mac,帶有最新發(fā)布的更新并且安裝了安全補丁。這樣你才能夠安裝需要的開發(fā)工具:最新版本的Xcode。
  • Xcode 7.3 或更新的版本。Xcode是用Swift寫代碼的主要開發(fā)工具。最小也需要Xcode 7.3版本,因為那個版本包含Swift 2.2。你可以免費從Mac App Store下載Xcode的最新版本,這里:http://apple.co/1FLn51R

如果你還沒有安裝Xcode最新版本,在繼續(xù)看下面的教程前要確定安裝。

如何使用這篇教程

每篇教程都會介紹觸手可及的話題理論,伴隨大量Swift代碼來示范在學習的實際的應(yīng)用程序。

教程里的所有代碼都是平臺中立的;這意味著不是為iOS、OS X或任何其它平臺而特定。代碼在playgrounds里運行,你在本篇中已經(jīng)學習了。

在剩下的教程里,你可以把代碼在自己的playground里輸入進去。這樣你就可以和代碼“玩耍”(play around),做一些改變立即就能看見代碼運行的結(jié)果。

剩下的教程里會貫穿實際小練習,都是簡短的練習,關(guān)于觸手可及的主題。每篇的末尾也有挑戰(zhàn),會有編程問題也會有長一點的代碼練習來測試你的知識。做完就能掌握大部分的Swift基礎(chǔ)知識。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容