數(shù)組(Arrays)
數(shù)組的簡(jiǎn)化語(yǔ)法(Array Type Shorthand Syntax)
- Array<Element>
- [Element] // 推薦用這種
創(chuàng)建一個(gè)空數(shù)組(Creating an Array with a Default Value)
- 可以使用構(gòu)造語(yǔ)法來(lái)創(chuàng)建一個(gè)由特定數(shù)據(jù)類型構(gòu)成的空數(shù)組:
- 在元素類型已知的情況下,我們可以使用空數(shù)組語(yǔ)句創(chuàng)建一個(gè)空數(shù)組,[]
(一對(duì)空方括號(hào))
var someInts = [Int]()
print("someInts is of type [Int] with \(someInts.count) items.")
// 打印 "someInts is of type [Int] with 0 items."
someInts.append(3)
// someInts 現(xiàn)在包含一個(gè) Int 值
someInts = []
// someInts 現(xiàn)在是空數(shù)組括授,但是仍然是 [Int] 類型的山卦。
創(chuàng)建一個(gè)帶有默認(rèn)值的數(shù)組(Creating an Array with a Default Value)
Swift 中的Array類型還提供一個(gè)可以創(chuàng)建特定大小并且所有數(shù)據(jù)都被默認(rèn)的構(gòu)造方法
通過兩個(gè)數(shù)組相加創(chuàng)建一個(gè)數(shù)組(Creating an Array by Adding Two Arrays Together)
我們可以使用加法操作符(+)來(lái)組合兩種已存在的相同類型數(shù)組。新數(shù)組的數(shù)據(jù)類型會(huì)被從兩個(gè)數(shù)組的數(shù)據(jù)類型中推斷出來(lái):
let threeDoubles = [Double](count: 3, repeatedValue: 0.0)
// threeDoubles is of type [Double], and equals [0.0, 0.0, 0.0]
let anotherThreeDoubles = [Double](count: 3, repeatedValue: 2.5)
// anotherThreeDoubles 被推斷為 [Double]氓辣,等價(jià)于 [2.5, 2.5, 2.5]
let sixDoubles = threeDoubles + anotherThreeDoubles
// sixDoubles 被推斷為 [Double]秒裕,等價(jià)于 [0.0, 0.0, 0.0, 2.5, 2.5, 2.5]
用字面量構(gòu)造數(shù)組(Creating an Array with an Array Literal)
我們可以使用字面量來(lái)進(jìn)行數(shù)組構(gòu)造,這是一種用一個(gè)或者多個(gè)數(shù)值構(gòu)造數(shù)組的簡(jiǎn)單方法钞啸。字面量是一系列由逗號(hào)分割并由方括號(hào)包含的數(shù)值:
訪問和修改數(shù)組(Accessing and Modifying an Array)
- 可以使用數(shù)組的只讀屬性count來(lái)獲取數(shù)組中的數(shù)據(jù)項(xiàng)數(shù)量:
- 使用布爾值屬性isEmpty作為檢查count屬性的值是否為 0 的捷徑
- 也可以使用append(_:)方法在數(shù)組后面添加新的數(shù)據(jù)項(xiàng)
- 使用加法賦值運(yùn)算符(+=)也可以直接在數(shù)組后面添加一個(gè)或多個(gè)擁有相同類型的數(shù)據(jù)項(xiàng)
- 可以直接使用下標(biāo)語(yǔ)法來(lái)獲取數(shù)組中的數(shù)據(jù)項(xiàng)几蜻,把我們需要的數(shù)據(jù)項(xiàng)的索引值放在直接放在數(shù)組名稱的方括號(hào)中
- 可以用下標(biāo)來(lái)改變某個(gè)已有索引值對(duì)應(yīng)的數(shù)據(jù)值
- 可以利用下標(biāo)來(lái)一次改變一系列數(shù)據(jù)值,即使新數(shù)據(jù)和原有數(shù)據(jù)的數(shù)量是不一樣的
- 調(diào)用數(shù)組的insert(_:atIndex:)方法來(lái)在某個(gè)具體索引值之前添加數(shù)據(jù)項(xiàng)
- 可以使用removeAtIndex(_:)方法來(lái)移除數(shù)組中的某一項(xiàng)
- 如果我們只想把數(shù)組中的最后一項(xiàng)移除体斩,可以使用removeLast()
方法
數(shù)組的遍歷(Iterating Over an Array)
- 可以使用for-in循環(huán)來(lái)遍歷所有數(shù)組中的數(shù)據(jù)項(xiàng)
- 如果我們同時(shí)需要每個(gè)數(shù)據(jù)項(xiàng)的值和索引值梭稚,可以使用enumerate()方法來(lái)進(jìn)行數(shù)組遍歷。enumerate()返回一個(gè)由每一個(gè)數(shù)據(jù)項(xiàng)索引值和數(shù)據(jù)值組成的元組硕勿。
var shoppingList = ["Eggs", "Milk"]
// shoppingList 已經(jīng)被構(gòu)造并且擁有兩個(gè)初始項(xiàng)哨毁。
print("The shopping list contains \(shoppingList.count) items.")
// 輸出 "The shopping list contains 2 items."(這個(gè)數(shù)組有2個(gè)項(xiàng))
if shoppingList.isEmpty {
print("The shopping list is empty.")
} else {
print("The shopping list is not empty.")
}
// 打印 "The shopping list is not empty."(shoppinglist 不是空的)
shoppingList.append("Flour")
// shoppingList 現(xiàn)在有3個(gè)數(shù)據(jù)項(xiàng),有人在攤煎餅
shoppingList += ["Baking Powder"]
// shoppingList 現(xiàn)在有四項(xiàng)了
shoppingList += ["Chocolate Spread", "Cheese", "Butter"]
// shoppingList 現(xiàn)在有七項(xiàng)了
var firstItem = shoppingList[0]
// 第一項(xiàng)是 "Eggs"
shoppingList[0] = "Six eggs"
// 其中的第一項(xiàng)現(xiàn)在是 "Six eggs" 而不是 "Eggs"
shoppingList[4...6] = ["Bananas", "Apples"]
// shoppingList 現(xiàn)在有6項(xiàng)
shoppingList.insert("Maple Syrup", atIndex: 0)
// shoppingList 現(xiàn)在有7項(xiàng)
// "Maple Syrup" 現(xiàn)在是這個(gè)列表中的第一項(xiàng)
let mapleSyrup = shoppingList.removeAtIndex(0)
// 索引值為0的數(shù)據(jù)項(xiàng)被移除
// shoppingList 現(xiàn)在只有6項(xiàng)源武,而且不包括 Maple Syrup
// mapleSyrup 常量的值等于被移除數(shù)據(jù)項(xiàng)的值 "Maple Syrup"
firstItem = shoppingList[0]
// firstItem 現(xiàn)在等于 "Six eggs"
let apples = shoppingList.removeLast()
// 數(shù)組的最后一項(xiàng)被移除了
// shoppingList 現(xiàn)在只有5項(xiàng)扼褪,不包括 Apples
// apples 常量的值現(xiàn)在等于 "Apples" 字符串
for item in shoppingList {
print(item)
}
// Six eggs
// Milk
// Flour
// Baking Powder
// Bananas
for (index, value) in shoppingList.enumerate() {
print("Item \(String(index + 1)): \(value)")
}
// Item 1: Six eggs
// Item 2: Milk
// Item 3: Flour
// Item 4: Baking Powder
// Item 5: Bananas
數(shù)組的下標(biāo)是整數(shù),比String的要好用
集合(Sets)
集合(Set)用來(lái)存儲(chǔ)相同類型并且沒有確定順序的值粱栖。當(dāng)集合元素順序不重要時(shí)或者希望確保每個(gè)元素只出現(xiàn)一次時(shí)可以使用集合而不是數(shù)組话浇。
集合類型語(yǔ)法(Set Type Syntax)
Swift 中的Set類型被寫為Set<Element>,這里的Element表示Set中允許存儲(chǔ)的類型闹究,和數(shù)組不同的是幔崖,集合沒有等價(jià)的簡(jiǎn)化形式。
創(chuàng)建和構(gòu)造一個(gè)空的集合(Creating and Initializing an Empty Set)
- 可以通過構(gòu)造器語(yǔ)法創(chuàng)建一個(gè)特定類型的空集合:
- 如果上下文提供了類型信息,可以通過一個(gè)空的數(shù)組字面量創(chuàng)建一個(gè)空的Set
var letters = Set<Character>()
print("letters is of type Set<Character> with \(letters.count) items.")
// 打印 "letters is of type Set<Character> with 0 items."
letters.insert("a")
// letters 現(xiàn)在含有1個(gè) Character 類型的值
letters = []
// letters 現(xiàn)在是一個(gè)空的 Set, 但是它依然是 Set<Character> 類型
用數(shù)組字面量創(chuàng)建集合(Creating a Set with an Array Literal)
- 可以使用數(shù)組字面量來(lái)構(gòu)造集合赏寇,并且可以使用簡(jiǎn)化形式寫一個(gè)或者多個(gè)值作為集合元素吉嫩。
- 一個(gè)Set類型不能從數(shù)組字面量中被單獨(dú)推斷出來(lái),因此Set類型必須顯式聲明嗅定。
訪問和修改一個(gè)集合(Accessing and Modifying a Set)
- 為了找出一個(gè)Set中元素的數(shù)量自娩,可以使用其只讀屬性count
- 使用布爾屬性isEmpty作為一個(gè)縮寫形式去檢查count屬性是否為0
- 你可以通過調(diào)用Set的insert(_:)方法來(lái)添加一個(gè)新元素
- 可以通過調(diào)用Set的remove(_:)方法去刪除一個(gè)元素,如果該值是該Set的一個(gè)元素則刪除該元素并且返回被刪除的元素值渠退,否則如果該Set不包含該值忙迁,則返回nil
- Set中的所有元素可以通過它的removeAll()方法刪除
- 使用contains(_:)方法去檢查Set中是否包含一個(gè)特定的值
遍歷一個(gè)集合(Iterating Over a Set)
- 可以在一個(gè)for-in循環(huán)中遍歷一個(gè)Set中的所有值
- Swift 的Set類型沒有確定的順序,為了按照特定順序來(lái)遍歷一個(gè)Set中的值可以使用sort()方法碎乃,它將根據(jù)提供的序列返回一個(gè)有序集合
var favoriteGenres: Set<String> = ["Rock", "Classical", "Hip hop"]
// favoriteGenres 被構(gòu)造成含有三個(gè)初始值的集合
// Set不能省<String>可以省略
// var favoriteGenres: Set = ["Rock", "Classical", "Hip hop"]
print("I have \(favoriteGenres.count) favorite music genres.")
// 打印 "I have 3 favorite music genres."
if favoriteGenres.isEmpty {
print("As far as music goes, I'm not picky.")
} else {
print("I have particular music preferences.")
}
// 打印 "I have particular music preferences."
favoriteGenres.insert("Jazz")
// favoriteGenres 現(xiàn)在包含4個(gè)元素
if let removedGenre = favoriteGenres.remove("Rock") {
print("\(removedGenre)? I'm over it.")
} else {
print("I never much cared for that.")
}
// 打印 "Rock? I'm over it."
if favoriteGenres.contains("Funk") {
print("I get up on the good foot.")
} else {
print("It's too funky in here.")
}
// 打印 "It's too funky in here."
for genre in favoriteGenres {
print("\(genre)")
}
// Classical
// Jazz
// Hip hop
for genre in favoriteGenres.sort() {
print("\(genre)")
}
// prints "Classical"
// prints "Hip hop"
// prints "Jazz
集合操作(Performing Set Operations)
基本集合操作(Fundamental Set Operations)
- 使用intersect(_:)方法根據(jù)兩個(gè)集合中都包含的值創(chuàng)建的一個(gè)新的集合姊扔。
- 使用exclusiveOr(_:)方法根據(jù)在一個(gè)集合中但不在兩個(gè)集合中的值創(chuàng)建一個(gè)新的集合。
- 使用union(_:)方法根據(jù)兩個(gè)集合的值創(chuàng)建一個(gè)新的集合梅誓。
- 使用subtract(_:)方法根據(jù)不在該集合中的值創(chuàng)建一個(gè)新的集合恰梢。
let oddDigits: Set = [1, 3, 5, 7, 9]
let evenDigits: Set = [0, 2, 4, 6, 8]
let singleDigitPrimeNumbers: Set = [2, 3, 5, 7]
oddDigits.union(evenDigits).sort()
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
oddDigits.intersect(evenDigits).sort()
// []
oddDigits.subtract(singleDigitPrimeNumbers).sort()
// [1, 9]
oddDigits.exclusiveOr(singleDigitPrimeNumbers).sort()
// [1, 2, 9]
集合成員關(guān)系和相等(Set Membership and Equality)
- 使用“是否相等”運(yùn)算符(==)來(lái)判斷兩個(gè)集合是否包含全部相同的值。
- 使用isSubsetOf(_:)方法來(lái)判斷一個(gè)集合中的值是否也被包含在另外一個(gè)集合中证九。
- 使用isSupersetOf(_:)方法來(lái)判斷一個(gè)集合中包含另一個(gè)集合中所有的值删豺。
- 使用isStrictSubsetOf(:)或者isStrictSupersetOf(:)方法來(lái)判斷一個(gè)集合是否是另外一個(gè)集合的子集合或者父集合并且兩個(gè)集合并不相等。
- 使用isDisjointWith(_:)方法來(lái)判斷兩個(gè)集合是否不含有相同的值(是否沒有交集)愧怜。
- b是a的子集
- b是a的嚴(yán)格子集
- a != c
- b和c不相關(guān)
let houseAnimals: Set = ["??", "??"]
let farmAnimals: Set = ["??", "??", "??", "??", "??"]
let cityAnimals: Set = ["??", "??"]
houseAnimals.isSubsetOf(farmAnimals)
// true
farmAnimals.isSupersetOf(houseAnimals)
// true
farmAnimals.isDisjointWith(cityAnimals)
// true
字典(Dictionaries)
字典是一種存儲(chǔ)多個(gè)相同類型的值的容器呀页。每個(gè)值(value)都關(guān)聯(lián)唯一的鍵(key),鍵作為字典中的這個(gè)值數(shù)據(jù)的標(biāo)識(shí)符拥坛。和數(shù)組中的數(shù)據(jù)項(xiàng)不同蓬蝶,字典中的數(shù)據(jù)項(xiàng)并沒有具體順序。我們?cè)谛枰ㄟ^標(biāo)識(shí)符(鍵)訪問數(shù)據(jù)的時(shí)候使用字典猜惋。
字典類型快捷語(yǔ)法(Dictionary Type Shorthand Syntax)
- 字典使用Dictionary<Key, Value>定義丸氛,其中Key是字典中鍵的數(shù)據(jù)類型,Value是字典中對(duì)應(yīng)于這些鍵所存儲(chǔ)值的數(shù)據(jù)類型著摔。
- 可以用[Key: Value]這樣快捷的形式去創(chuàng)建一個(gè)字典類型缓窜。推薦用這種
Creating an Empty Dictionary
- 可以像數(shù)組一樣使用構(gòu)造語(yǔ)法創(chuàng)建一個(gè)擁有確定類型的空字典
- 如果上下文已經(jīng)提供了類型信息,我們可以使用空字典字面量來(lái)創(chuàng)建一個(gè)空字典谍咆,記作[:](中括號(hào)中放一個(gè)冒號(hào)):
var namesOfIntegers = [Int: String]()
// namesOfIntegers 是一個(gè)空的 [Int: String] 字典
namesOfIntegers[16] = "sixteen"
// namesOfIntegers 現(xiàn)在包含一個(gè)鍵值對(duì)
namesOfIntegers = [:]
// namesOfIntegers 又成為了一個(gè) [Int: String] 類型的空字典
用字典字面量創(chuàng)建字典(Creating a Dictionary with a Dictionary Literal)
- 可以使用字典字面量來(lái)構(gòu)造字典禾锤,這和我們剛才介紹過的數(shù)組字面量擁有相似語(yǔ)法。字典字面量是一種將一個(gè)或多個(gè)鍵值對(duì)寫作Dictionary
集合的快捷途徑摹察。 - 在用字典字面量構(gòu)造字典時(shí)矾利,如果它的鍵和值都有各自一致的類型捣鲸,那么就不必寫出字典的類型亿驾。
訪問和修改字典(Accessing and Modifying a Dictionary)
- 可以通過字典的只讀屬性count來(lái)獲取某個(gè)字典的數(shù)據(jù)項(xiàng)數(shù)量
- 使用布爾屬性isEmpty來(lái)快捷地檢查字典的count屬性是否等于0
- 可以在字典中使用下標(biāo)語(yǔ)法來(lái)添加新的數(shù)據(jù)項(xiàng),如果key已經(jīng)存在峭状,則會(huì)改變對(duì)應(yīng)key的值
- updateValue(_:forKey:)方法在這個(gè)鍵不存在對(duì)應(yīng)值的時(shí)候會(huì)設(shè)置新值或者在存在時(shí)更新已存在的值。返回更新值之前的原值逼争,是一個(gè)可選值(新建的情況返回nil)优床。
- 可以使用下標(biāo)語(yǔ)法來(lái)通過給某個(gè)鍵的對(duì)應(yīng)值賦值為nil來(lái)從字典里移除一個(gè)鍵值對(duì)
- removeValueForKey(_:)方法也可以用來(lái)在字典中移除鍵值對(duì)。這個(gè)方法在鍵值對(duì)存在的情況下會(huì)移除該鍵值對(duì)并且返回被移除的值或者在沒有值的情況下返回nil
字典遍歷(Iterating Over a Dictionary)
- 可以使用for-in循環(huán)來(lái)遍歷某個(gè)字典中的鍵值對(duì)氮凝。每一個(gè)字典中的數(shù)據(jù)項(xiàng)都以(key, value)元組形式返回羔巢,并且我們可以使用臨時(shí)常量或者變量來(lái)分解這些元組
- 通過訪問keys或者values屬性,我們也可以遍歷字典的鍵或者值:
- 如果我們只是需要使用某個(gè)字典的鍵集合或者值集合來(lái)作為某個(gè)接受Array實(shí)例的 API 的參數(shù)罩阵,可以直接使用keys或者values屬性構(gòu)造一個(gè)新數(shù)組
- 為了以特定的順序遍歷字典的鍵或值,可以對(duì)字典的keys或values屬性使用sort()方法启摄。
var airports = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
// var airports: [String: String] = ["YYZ": "Toronto Pearson", "DUB": "Dublin"]
print("The dictionary of airports contains \(airports.count) items.")
// 打印 "The dictionary of airports contains 2 items."(這個(gè)字典有兩個(gè)數(shù)據(jù)項(xiàng))
if airports.isEmpty {
print("The airports dictionary is empty.")
} else {
print("The airports dictionary is not empty.")
}
// 打印 "The airports dictionary is not empty."
airports["LHR"] = "London"
// airports 字典現(xiàn)在有三個(gè)數(shù)據(jù)項(xiàng)
airports["LHR"] = "London Heathrow"
// "LHR"對(duì)應(yīng)的值 被改為 "London Heathrow
if let oldValue = airports.updateValue("Dublin Airport", forKey: "DUB") {
print("The old value for DUB was \(oldValue).")
}
// 輸出 "The old value for DUB was Dublin."
if let airportName = airports["DUB"] {
print("The name of the airport is \(airportName).")
} else {
print("That airport is not in the airports dictionary.")
}
// 打印 "The name of the airport is Dublin Airport."
// 網(wǎng)絡(luò)來(lái)的數(shù)據(jù)稿壁,最好都采用這種結(jié)構(gòu),不要怕麻煩歉备,安全是第一位的
airports["APL"] = "Apple Internation"
// "Apple Internation" 不是真的 APL 機(jī)場(chǎng), 刪除它
airports["APL"] = nil
// APL 現(xiàn)在被移除了
if let removedValue = airports.removeValueForKey("DUB") {
print("The removed airport's name is \(removedValue).")
} else {
print("The airports dictionary does not contain a value for DUB.")
}
// prints "The removed airport's name is Dublin Airport."
for (airportCode, airportName) in airports {
print("\(airportCode): \(airportName)")
}
// YYZ: Toronto Pearson
// LHR: London Heathrow
for airportCode in airports.keys {
print("Airport code: \(airportCode)")
}
// Airport code: YYZ
// Airport code: LHR
for airportName in airports.values {
print("Airport name: \(airportName)")
}
// Airport name: Toronto Pearson
// Airport name: London Heathrow
let airportCodes = [String](airports.keys)
// airportCodes 是 ["YYZ", "LHR"]
let airportNames = [String](airports.values)
// airportNames 是 ["Toronto Pearson", "London Heathrow"]