Swift 的集合表現(xiàn)形式由數(shù)組和字典組成。它可以完美的存儲(chǔ)任何呢想存儲(chǔ)的東西。
數(shù)組是一個(gè)同類型的序列化列表集合,它用來存儲(chǔ)相同類型的不同值。字典也是一個(gè)數(shù)組,但它的存值方式類似于Map,通過一對(duì)一鍵來綁定值,是一組非序列化集合。
在Swift中,數(shù)組和字典的鍵和值都必須明確它的類型。
這意味這數(shù)組和字典不會(huì)插入一個(gè)錯(cuò)誤的類型的值,以致于出錯(cuò)。這也意味著當(dāng)你在數(shù)組和字典中取回?cái)?shù)值的時(shí)候能夠確定它的類型。
Swift 使用確定的集合類型可以保證代碼工作是不會(huì)出錯(cuò),和讓你在開發(fā)階段就能更早的捕獲錯(cuò)誤。
1、數(shù)組
數(shù)組是儲(chǔ)存同類型不同值的序列化列表。同樣的值可以在數(shù)組的不同位置出現(xiàn)多次。
Swift數(shù)組是儲(chǔ)存確定的值,這個(gè)Objective-C中的NSArray和NSMutableArray類是有區(qū)別的。因?yàn)樗鼈兪莾?chǔ)存各種的對(duì)象,而且并不提供返回任何有關(guān)對(duì)象的具體信息。在Swift中,無論是確定的聲明,還是隱式的聲明,數(shù)組是非常確定它自身是儲(chǔ)存什么樣的類型,而且,它并不一定要求儲(chǔ)存的是類對(duì)象。所以Swift數(shù)組是類型安全的,因?yàn)樗恢倍即_定它自身所能包含的值。
數(shù)組的簡(jiǎn)略語法
定義數(shù)組的完整寫法是Array<SomeType>。其中SomeType是你想要包含的類型。你也可以使用類似于SomeType[]這樣的簡(jiǎn)略語法。雖然這兩種方法在功能上是相同的。但是我們更推薦后者,而且它會(huì)一直貫穿于本書。
數(shù)組實(shí)量(Array Literals)
你可以用一個(gè)數(shù)組實(shí)量(Array Literals)來初始化一個(gè)數(shù)組,它是用簡(jiǎn)略寫法來創(chuàng)建一個(gè)包含一個(gè)或多個(gè)的值的數(shù)組。一個(gè)數(shù)組實(shí)量(Array Literals)是由它包含的值,“,”分隔符 已經(jīng)包括以上內(nèi)容的中括號(hào)對(duì)“[]”組成:

下面的例子創(chuàng)建一個(gè)叫shoppinglist,儲(chǔ)存字符串(String)類型的數(shù)組。

shoppinglist變量被定義為字符串(String)類型的數(shù)組,寫作String[]。因?yàn)檫@個(gè)數(shù)組被確定為字符串類型(String),所以它只能儲(chǔ)存字符串(String)類型的值。在這里,用兩個(gè)字符串類型的值(”Eggs” and “Milk”)和數(shù)組實(shí)量(Array Literals)的寫法來初始化shoppingList數(shù)組。
注意
shoppingList數(shù)組是被定義為一個(gè)變量(使用var 標(biāo)識(shí)符)而不是常量(使用let 標(biāo)識(shí)符),所以在下面的例子可以直接添加元素。
在這個(gè)例子中,數(shù)組實(shí)量(Array Literals)只包含兩個(gè)字符串類型的值,這符合了shoppingList變量的定義(只能包含字符串(String)類型的數(shù)組),所以被分配的數(shù)組實(shí)量(Array Literals)被允許用兩個(gè)字符串類型的值來初始化。
得益于Swift的類型推斷,當(dāng)你用相同類型的值來初始化時(shí),你可以不寫明類型。初始化shoppingList可以用下面這個(gè)方法來代替。

因?yàn)閿?shù)組實(shí)量(Array Literals)中所有的值都是同類型的,所以Swift能夠推斷shoppingList的類型為字符串?dāng)?shù)組(String[])。
讀取和修改數(shù)組
你可以通過方法和屬性,或者下標(biāo)來讀取和修改數(shù)組。
通過只讀屬性count來讀取數(shù)組的長(zhǎng)度;

通過一個(gè)返回布爾類型的isEmpty屬性檢查數(shù)組的長(zhǎng)度是否為0

在數(shù)組末尾增加一個(gè)元素可以通過append方法

甚至,還可以用(+=)操作符來把一個(gè)元素添加到數(shù)組末尾

你也可以用(+=)操作符來把一個(gè)數(shù)組添加到另一個(gè)數(shù)組的末尾

從數(shù)組中取出一個(gè)值可以使用下標(biāo)語法。如果你知道一個(gè)元素的索引值,你可以數(shù)組名后面的中括號(hào)中填寫索引值來獲取這個(gè)元素

注意
數(shù)組的第一個(gè)元素的索引值為0,不為1,Swift的數(shù)組總是索引0;
你可以使用下標(biāo)語法通過索引修改已經(jīng)存在的值。

你可以使用下標(biāo)語法一次性改變一系列的值,盡管修改的區(qū)域遠(yuǎn)遠(yuǎn)大于要修改的值。在下面的雷子中, 替換掉 “Chocolate SPRead”, “Cheese”,”Butter”,”Bananas”,”Apples”:

注意,你不能使用下標(biāo)語法在數(shù)組中添加一個(gè)元素,如果你嘗試使用下標(biāo)語法來獲取或者設(shè)置一個(gè)元素,你將得到一個(gè)運(yùn)行時(shí)的錯(cuò)誤。盡管如此,你可以通過count屬性驗(yàn)證索引是否正確再使用它。當(dāng)count為0時(shí)(意味著數(shù)組為空),則count-1超出了索引的有效范圍,因?yàn)閿?shù)組的索引總是從0開始。
在一個(gè)特定的索引位置插入一個(gè)值,可以使用insert(atIndex:)方法

這里調(diào)用insert方法指明在shoppingList的索引為0的位置中插入一個(gè)新元素 “Maple Syrup”
同理,你可以調(diào)用removeAtIndex方法移除特定的元素。這個(gè)方法移除特定索引位置的元素,已經(jīng)返回這個(gè)被移除的元素(盡管你并不關(guān)心這個(gè)返回值)。

當(dāng)元素被移除的,數(shù)組空缺的位置將會(huì)被填補(bǔ),所以現(xiàn)在索引位置為0的元素再一次等于”Six eggs”:

如果你從數(shù)組中移除最后一個(gè)元素,使用removeLast方法比removeAtIndex更方便,因?yàn)楹笳咝枰ㄟ^count屬性計(jì)算數(shù)組的長(zhǎng)度。和removeAtIndex方法一樣,removeLast會(huì)返回被移除的元素。

遍歷數(shù)組
可以使用for-in循環(huán)來遍歷數(shù)組中的值

如果需要每一個(gè)元素的整形的索引值,使用enumerate函數(shù)代替會(huì)更方便,enumerate函數(shù)對(duì)于每一個(gè)元素都會(huì)返回一個(gè)包含元素的索引和值的元組(tuple)。你可以在遍歷部分分解元祖并儲(chǔ)存在臨時(shí)變量或者常量中。

創(chuàng)建和初始化數(shù)組
創(chuàng)建一個(gè)空的數(shù)組和確定的類型(不包含初始化值)使用的初始化語法:

注意
someInt變量被確定為Int[],因?yàn)樗褂蒙蒊nt[]的初始化方法。
或者,如果上下文(context)已經(jīng)提供類型信息,例如函數(shù)參數(shù)或者已經(jīng)確定類型的常量和變量,你可以從空的數(shù)組實(shí)量(Array Literals)創(chuàng)建一個(gè)空數(shù)組,寫作[](空的中括號(hào)對(duì))。

Swift數(shù)組類型也提供初始化方法來創(chuàng)建確定長(zhǎng)度和提供默認(rèn)數(shù)值的數(shù)組。你可以通過這個(gè)初始化方法增加一個(gè)新的數(shù)組,元素的數(shù)量成為count,合適的默認(rèn)值為repeatedValue

得益于類型推斷,你并不需要指明這個(gè)數(shù)組儲(chǔ)存的類型就能使用這個(gè)初始化方法,因?yàn)樗鼜哪J(rèn)值中就能推斷出來。

最后,你可以使用(+)操作符就能創(chuàng)建一個(gè)新的數(shù)組,把兩個(gè)存在的數(shù)組添加進(jìn)來
這個(gè)新的數(shù)組類型從你添加的兩個(gè)數(shù)組中推斷出來

2、字典
字典是儲(chǔ)存同一類型但是不同值的容易。每一個(gè)值都對(duì)應(yīng)這一個(gè)唯一的鍵(Key),就像是字典內(nèi)的每一個(gè)值都有一個(gè)標(biāo)識(shí)符。和數(shù)組內(nèi)的元素是由區(qū)別的,字典內(nèi)的元素是沒有特殊的序列的。當(dāng)你需要根據(jù)標(biāo)識(shí)符來查找批量的值時(shí),就可以使用字典。同樣的,真實(shí)
的物品字典常常用來當(dāng)作查找特定字典的標(biāo)識(shí)符。
Swift字典時(shí)儲(chǔ)存一個(gè)類型的具體的鍵和值,和Objective-C的NSDictionary 和NSMutableDictionary由一定的區(qū)別,因?yàn)樗鼈兪鞘褂酶鞣N的對(duì)象來作為它們的鍵和值,而且并不提供任何有關(guān)對(duì)象的具體信息。在Swift中,對(duì)于一個(gè)特定的字典,它所能儲(chǔ)存的鍵和值都是確定的,無論是明確聲明的類型還是隱式推斷的類型。
Swift的字典寫法是Dictionary<KeyType,ValueType>,KeyType是你想要儲(chǔ)存的鍵,ValueType是你想要儲(chǔ)存的值。
唯一的限制就是KeyType必須是可哈希的(hashable)——就是提供一個(gè)形式讓它們自身是獨(dú)立識(shí)別的。Swift的所有基礎(chǔ)類型(例如字符串(String),整形(Int),雙精度(Double)和布爾(Bool))在默認(rèn)是可哈希的(hashable),和這些類型都常常用語當(dāng)作字典的鍵。枚舉成員值不需要協(xié)助值(associated values)(具體描述在 Enumerations)也是因?yàn)樗鼈兡J(rèn)也是可哈希的(hashable)。
字典實(shí)量(Dictionary Literals)
你可以直接用一個(gè)字典實(shí)量(Dictionary Literals)初始化一個(gè)字典。和前面定義一個(gè)數(shù)組實(shí)量(Array Literals)的語法一樣。字典實(shí)量(Dictionary Literals)就是使用簡(jiǎn)略寫法直接寫一個(gè)或者多個(gè)的鍵值對(duì)來定義一個(gè)字典。
一個(gè)鍵值對(duì)是一個(gè)鍵和值的組合。在字典實(shí)量(Dictionary Literals)里面,每一個(gè)鍵值對(duì)總是用一個(gè)冒號(hào)把鍵和值分割。鍵值對(duì)的寫法就想是一個(gè)列表,使用逗號(hào)分割,并被一對(duì)中括號(hào)[]包含著:

在下面的例子,將會(huì)創(chuàng)建一個(gè)字典來儲(chǔ)存國(guó)際機(jī)場(chǎng)的名字。在這個(gè)字典里面,鍵是三個(gè)字的國(guó)際航空運(yùn)送協(xié)會(huì)代碼,以及它的值是機(jī)場(chǎng)的名稱:

airport字典被定義為一個(gè)類型為Dictionary<String, String>,這意味這,這個(gè)字典的鍵類型是字符串String,和它的值的類型也是String。
注意
airport字典是被定義為一個(gè)變量(使用var 標(biāo)識(shí)符)而不是常量(使用let 標(biāo)識(shí)符),所以在下面的例子可以直接添加元素。
airport字典使用一個(gè)包含兩個(gè)鍵值對(duì)的字典實(shí)量(Dictionary Literals)來初始化。第一對(duì)由一個(gè)叫“TYO”的鍵和一個(gè)叫“Tokyo”的值,第二對(duì)有一個(gè)叫“DUB”的鍵和一個(gè)叫“Dublin”的值。
這個(gè)字典實(shí)量(Dictionary Literals)包含兩個(gè)字符串(String):字符串對(duì)。這符合airport變量定義的類型(一個(gè)字典只包括字符串(String)鍵和字符串(String)值),所以在分配字典實(shí)量(Dictionary Literals)的時(shí)候被允許作為airport字典的兩個(gè)初始化元素。
和數(shù)組一樣,如果你初始化一個(gè)字典的時(shí)候使用相同的類型,你可以不指明字典的類型。
airport初始化可以用下面這個(gè)簡(jiǎn)略寫法來代替:

因?yàn)樗械逆I在字面上都是相同的類型,同樣,所有的值也是同樣的類型,所以Swift可以推斷為Dictionary<String, String>是airports字典的正確類型。
讀取和修改字典
你可以通過屬性,方法或者下標(biāo)來讀取和修改字典。和數(shù)組一樣,你使用只讀的count屬性來檢查字典(Dictionary)包含多少個(gè)元素。

你可以使用下標(biāo)語法給一個(gè)字典添加一個(gè)元素。使用合適類型作為新的鍵,并分配給它一個(gè)合適的值

你也可以使用下標(biāo)語法去改變一個(gè)特定鍵所關(guān)聯(lián)的值。

同樣, 使用字典的updateValue(forKey:) 方法去設(shè)置或者更新一個(gè)特定鍵的值 . 和上面的下標(biāo)例子一樣, updateValue(forKey:) 方法如果鍵不存在則會(huì)設(shè)置它的值,如果鍵存在則會(huì)更新它的值, 和下標(biāo)不一樣是, updateValue(forKey:) 方法 如果更新時(shí),會(huì)返回原來舊的值rThis enables you to 可以使用這個(gè)來判斷是否發(fā)生了更新。

你也可以使用下標(biāo)語法通過特定的鍵去讀取一個(gè)值。因?yàn)槿绻闹挡淮嬖诘臅r(shí)候,可以返回他的鍵,字典的下標(biāo)語法會(huì)返回一個(gè)字典的值的類型的可選值。如果字典中的鍵包含對(duì)應(yīng)的值,這字典下標(biāo)語法會(huì)返回這個(gè)鍵所對(duì)應(yīng)的值,否則返回nil

你可以使用下標(biāo)語法把他的值分配為nil,來移除這個(gè)鍵值對(duì)。

// APL 已經(jīng)從字典中被移除
同樣,從一個(gè)字典中移除一個(gè)鍵值對(duì)可以使用removeValueForKey方法,這個(gè)方法如果存在鍵所對(duì)應(yīng)的值,則移除一個(gè)鍵值對(duì),并返回被移除的值,否則返回nil。

遍歷字典
你可以使用一個(gè)for-in循環(huán)來遍歷字典的鍵值對(duì)。字典中的每一個(gè)元素都會(huì)返回一個(gè)元祖(tuple),你可以在循環(huán)部分分解這個(gè)元祖,并用臨時(shí)變量或者常量來儲(chǔ)存它。

你也可以讀取字典的keys屬性或者values屬性來遍歷這個(gè)字典的鍵或值的集合。

如果你需要一個(gè)接口來創(chuàng)建一個(gè)字典的鍵或者值的數(shù)組實(shí)例,你可以使用keys或者values屬性來初始化一個(gè)數(shù)值。

注意
Swift中的字典類型是非序列化集合,如果你需要序列化取回鍵,值,或者鍵值對(duì),遍歷字典不具體敘述。
創(chuàng)建一個(gè)空字典
和字典一樣,你可以使用確定類型的語法創(chuàng)建一個(gè)空的字典。

這個(gè)例子創(chuàng)建一個(gè)Int,String類型的字典來儲(chǔ)存可讀性較好的整數(shù)值。它的鍵是Int類型,以及它們的值是String類型。
如果 上下文(context )中已經(jīng)提供類型信息,可用一個(gè)字典實(shí)量(Dictionary Literal)創(chuàng)建一個(gè)空的字典,寫作[;](由一對(duì)[]包含一個(gè)冒號(hào):)

注意
在這個(gè)場(chǎng)景,Swift數(shù)組和字典類型是一個(gè)內(nèi)置的集合。
3、可變集合類型
數(shù)組和字典都是在一個(gè)集合中一起儲(chǔ)存不同的變量.如果你創(chuàng)建一個(gè)數(shù)組或者字典,再包含一個(gè)變量,創(chuàng)建的這個(gè)變量被稱為可變的(mutable) 這意味這,你可以在創(chuàng)建之后增加更多的元素來改變這個(gè)集合的長(zhǎng)度,或者移除已經(jīng)包含的。 相反的, 如果你把一個(gè)數(shù)組或者字典定義為常量,則這個(gè)數(shù)組或者字典不是可變的,他們的長(zhǎng)度并不能被改變。
在字典中,不可變也意味著你不能替換已經(jīng)存在的鍵的值。一個(gè)不可變字典,一旦被設(shè)置就不能改變。
數(shù)組的不可變有一點(diǎn)點(diǎn)的不同。然而,你仍然不能做任何有可能修改不可變數(shù)組的行為。但是你可以重新設(shè)置一個(gè)已經(jīng)存在的索引,這使得當(dāng)Swift的數(shù)組的長(zhǎng)度確定時(shí),能更好地優(yōu)化數(shù)組的性能。
擁有可變行為的數(shù)組也影響著數(shù)組實(shí)例的分配和修改。
注意
在所有的例子中,這是一個(gè)好的練習(xí)去創(chuàng)建不可變集合,當(dāng)數(shù)組的長(zhǎng)度不需要被改變。
我確信Swift編譯器能優(yōu)化好你所創(chuàng)建的集合。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注