[swift-day03-集合]
- Swift 語言提供Arrays、Sets和Dictionaries三種基本的集合類型用來存儲集合數據。數組(Arrays)是有序數據的集。集合(Sets)是無序無重復數據的集。字典(Dictionaries)是無序的鍵值對的集。如果創建一個Arrays、Sets或Dictionaries并且把它分配成一個變量,這個集合將會是可變的。這意味著我們可以在創建之后添加更多或移除已存在的數據項,或者改變集合中的數據項。如果我們把Arrays、Sets或Dictionaries分配成常量,那么它就是不可變的,它的大小和內容都不能被改變。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//Swift 語言提供Arrays、Sets和Dictionaries三種基本的集合類型用來存儲集合數據。數組(Arrays)是有序數據的集。集合(Sets)是無序無重復數據的集。字典(Dictionaries)是無序的鍵值對的集。如果創建一個Arrays、Sets或Dictionaries并且把它分配成一個變量,這個集合將會是可變的。這意味著我們可以在創建之后添加更多或移除已存在的數據項,或者改變集合中的數據項。如果我們把Arrays、Sets或Dictionaries分配成常量,那么它就是不可變的,它的大小和內容都不能被改變。
//------------數組---------------
//寫 Swift 數組應該遵循像Array<Element>這樣的形式,其中Element是這個數組中唯一允許存在的數據類型。我們也可以使用像[Element]這樣的簡單語法
//創建一個空的數組,構造語法來創建一個由特定數據類型構成的空數組
var emptyArry = [Int]();//通過構造函數的類型,someInts的值類型被推斷為[Int]
//一個函數參數或者一個已經定義好類型的常量或者變量,我們可以使用空數組語句創建一個空數組,它的寫法很簡單:[]
emptyArry.append(3)//現在包涵一個Int值
emptyArry = [];//emotyArray 現在是空數組 ,但依舊是[Int]類型的
//Swift 中的Array類型還提供一個可以創建特定大小并且所有數據都被默認的構造方法。我們可以把準備加入新數組的數據項數量(count)和適當類型的初始值(repeatedValue)傳入數組構造函數
var createDouble = [Double](count: 3, repeatedValue: 1.0);//等價于 [1.0,1.0,1.0]
//使用加法操作符(+)來組合兩種已存在的相同類型數組。新數組的數據類型會被從兩個數組的數據類型中推斷出來
var anthonerDouble = Array(count: 3, repeatedValue: 2.0);// anthonerDouble 被推斷為 [Double],等價于 [2.0, 2.0, 2.0]
var twoDouble = createDouble + anthonerDouble;//twoDouble 被推斷為 [Double],等價于 [1.0, 1.0, 1.0, 2.0, 2.0, 2.0]
print(twoDouble)
//我們可以使用字面量來進行數組構造,這是一種用一個或者多個數值構造數組的簡單方法。字面量是一系列由逗號分割并由方括號包含的數值:[value 1, value 2, value 3]
var exampleArray:[String] = ["peng","lei"];//量被聲明為“字符串值類型的數組“,記作[String]。 因為這個數組被規定只有String一種數據結構,所以只有String類型可以在其中被存取。 在這里,exampleArrayt數組由兩個String值("peng" 和"lei")構造,并且由字面量定義
//字面量僅僅包含兩個String值。匹配了該數組的變量聲明(只能包含String的數組),所以這個字面量的分配過程可以作為用兩個初始項來構造shoppinglist的一種方式。由于 Swift 的類型推斷機制,當我們用字面量構造只擁有相同類型值數組的時候,我們不必把數組的類型定義清楚。 exampleArray的構造也可以這樣寫:var exampleArray = ["peng","lei"];
//使用數組的只讀屬性count來獲取數組中的數據項數量
print(exampleArray.count)
//使用布爾值屬性isEmpty作為檢查count屬性的值是否為 0
if exampleArray.isEmpty{
print("The exampleArray list is empty.")
}
//使用append(_:)方法在數組后面添加新的數據項:
exampleArray.append("I Love you")
print(exampleArray)//輸出結果["peng", "lei", "I Love you"]
//使用加法賦值運算符(+=)也可以直接在數組后面添加一個或多個擁有相同類型的數據項
exampleArray += ["peng"];
print(exampleArray)//輸出結果["peng", "lei", "I Love you", "peng"]
//直接使用下標語法來獲取數組中的數據項,把我們需要的數據項的索引值放在直接放在數組名稱的方括號中
var firstItem = exampleArray[0];
//用下標來改變某個已有索引值對應的數據值
exampleArray[0] = "haha";//現在其第一項變為了haha
//可以利用下標來一次改變一系列數據值,即使新數據和原有數據的數量是不一樣的
exampleArray[1...3] = ["p","l"];
print(exampleArray)//輸出結果["haha", "p", "l"]
//調用數組的insert(_:atIndex:)方法來在某個具體索引值之前添加數據項
exampleArray .insert("peng", atIndex: 0)
print(exampleArray)//["peng", "haha", "p", "l"]
//使用removeAtIndex(_:)方法來移除數組中的某一項。這個方法把數組在特定索引值中存儲的數據項移除并且返回這個被移除的數據項(我們不需要的時候就可以無視它)
let indexRemove = exampleArray.removeAtIndex(0)
print(exampleArray,indexRemove)//["haha", "p", "l"] peng
//數組遍歷
//使用for-in循環來遍歷所有數組中的數據項
for item in exampleArray{
print(item)
}
//同時需要每個數據項的值和索引值,可以使用enumerate()方法來進行數組遍歷。enumerate()返回一個由每一個數據項索引值和數據值組成的元組。我們可以把這個元組分解成臨時常量或者變量來進行遍歷:
for (index,value) in exampleArray.enumerate(){
print("Item \(index+1):\(value)")
}
//-----------------------------集合---------------------------
//集合(Set)用來存儲相同類型并且沒有確定順序的值。當集合元素順序不重要時或者希望確保每個元素只出現一次時可以使用集合而不是數組。
//Swift 中的Set類型被寫為Set<Element>,這里的Element表示Set中允許存儲的類型,和數組不同的是,集合沒有等價的簡化形式
//通過構造器語法創建一個特定類型的空集合
var letter = Set<Character>()
//如果上下文提供了類型信息,比如作為函數的參數或者已知類型的變量或常量,我們可以通過一個空的數組字面量創建一個空的Set
letter.insert("a")//現在包含一個元素
letter = [] //letter 現在是空的, 但是它依然是 Set<Character> 類型
//使用數組字面量來構造集合,并且可以使用簡化形式寫一個或者多個值作為集合元素
var set1:Set<String> = ["one","two","three"];//變量被聲明為“一個String值的集合”,寫為Set<String>。由于這個特定的集合含有指定String類型的值,所以它只允許存儲String類型值,有三個String類型的初始值("one","two"和"three"),并以數組字面量的方式出現
//由于 Swift 的類型推斷功能,如果你想使用一個數組字面量構造一個Set并且該數組字面量中的所有元素類型相同,那么你無須寫出Set的具體類型。favoriteGenres的構造形式可以采用簡化的方式代替
var set2 :Set = ["one","two","three"];
//和數組一樣,找出一個Set中元素的數量,可以使用其只讀屬性count
print(set1.count)
//使用布爾屬性isEmpty作為一個縮寫形式去檢查count屬性是否為0
if set1.isEmpty{
print("hh")
}
//調用Set的insert(_:)方法來添加一個新元素
set1.insert("four")
//通過調用Set的remove(_:)方法去刪除一個元素,如果該值是該Set的一個元素則刪除該元素并且返回被刪除的元素值,否則如果該Set不包含該值,則返回nil。另外,Set中的所有元素可以通過它的removeAll()方法刪除
let removeSet = set1.remove("four");
//for-in循環中遍歷一個Set中的所有值。
for item in set1{
print(item)
}
//Swift 的Set類型沒有確定的順序,為了按照特定順序來遍歷一個Set中的值可以使用sort()方法,它將根據提供的序列返回一個有序集合.
for item in set1.sort(){
print("\(item)");
}
//集合的之間的幾種操作
// 使用intersect(_:)方法根據兩個集合中都包含的值創建的一個新的集合。
// 使用exclusiveOr(_:)方法根據在一個集合中但不在兩個集合中的值創建一個新的集合。
// 使用union(_:)方法根據兩個集合的值創建一個新的集合。
// 使用subtract(_:)方法根據不在該集合中的值創建一個新的集合
let oneSet: Set = [0,1,2];
let twoSet: Set = [2,3,4,5,6];
let threeSet:Set = [5,6,7,8,9];
print(oneSet.union(twoSet).sort())//輸出[0, 1, 2, 3, 4, 5, 6]
print(oneSet.intersect(twoSet).sort())//輸出[2]
print(twoSet .subtract(threeSet).sort())//輸出[2, 3, 4]
print(twoSet.exclusiveOr(threeSet).sort())//輸出[2, 3, 4, 7, 8, 9]
//包含關系
// 使用“是否相等”運算符(==)來判斷兩個集合是否包含全部相同的值。
// 使用isSubsetOf(_:)方法來判斷一個集合中的值是否也被包含在另外一個集合中。
// 使用isSupersetOf(_:)方法來判斷一個集合中包含另一個集合中所有的值。
// 使用isStrictSubsetOf(_:)或者isStrictSupersetOf(_:)方法來判斷一個集合是否是另外一個集合的子集合或者父集合并且兩個集合并不相等。
// 使用isDisjointWith(_:)方法來判斷兩個集合是否不含有相同的值(是否沒有交集)。
let fourSet : Set = [0,1,2,3,4,5,6,7,8,9];
print(oneSet == twoSet)//false
print(oneSet.isSubsetOf(fourSet))//true
print(oneSet.isSupersetOf(oneSet))//true
print(oneSet.isStrictSubsetOf(fourSet))//true
print(oneSet.isDisjointWith(fourSet))//false
//------------------------字典--------------
//Swift 的字典使用Dictionary<Key, Value>定義,其中Key是字典中鍵的數據類型,Value是字典中對應于這些鍵所存儲值的數據類型,也可以用[Key: Value]這樣快捷的形式去創建一個字典類型。雖然這兩種形式功能上相同,但是后者是首選
//可以像數組一樣使用構造語法創建一個擁有確定類型的空字典:
var dict1 = [Int:String]()//一個空的 [Int: String] 字典
//如果上下文已經提供了類型信息,我們可以使用空字典字面量來創建一個空字典,記作[:](中括號中放一個冒號):
dict1[16] = "peng";//現在包含一個鍵值對
dict1 = [:];//dict 又成為了一個 [Int: String] 類型的空字典
//可以使用字典字面量來構造字典,這和我們剛才介紹過的數組字面量擁有相似語法。字典字面量是一種將一個或多個鍵值對寫作Dictionary集合的快捷途徑。
//格式[key 1: value 1, key 2: value 2, key 3: value 3]
var stringDic:[String:String] = ["one":"1","two":"2"];//字典語句包含了兩個String: String類型的鍵值對
//和數組一樣,我們在用字典字面量構造字典時,如果它的鍵和值都有各自一致的類型,那么就不必寫出字典的類型,stringDic= ["one":"1","two":"2"],因為這個語句中所有的鍵和值都各自擁有相同的數據類型,Swift 可以推斷出Dictionary<String, String>是airports字典的正確類型。
//和上面兩個數據類型一樣,可以通過字典的只讀屬性count來獲取某個字典的數據項數量,使用布爾屬性isEmpty來快捷地檢查字典的count屬性是否等于0,這里不再舉例
//可以在字典中使用下標語法來添加新的數據項。可以使用一個恰當類型的鍵作為下標索引,并且分配恰當類型的新值
stringDic["three"] = "3";//此時增加了一個數據項
//也可以使用下標語法來改變特定鍵對應的值
stringDic["three"] = "san";//此時“three”對應的值改為了san
//作為另一種下標方法,字典的updateValue(_:forKey:)方法可以設置或者更新特定鍵對應的值。就像上面所示的下標示例,updateValue(_:forKey:)方法在這個鍵不存在對應值的時候會設置新值或者在存在時更新已存在的值。和上面的下標方法不同的,updateValue(_:forKey:)這個方法返回更新值之前的原值。這樣使得我們可以檢查更新是否成功。
//updateValue(_:forKey:)方法會返回對應值的類型的可選值。舉例來說:對于存儲String值的字典,這個函數會返回一個String?或者“可選 String”類型的值。
//如果有值存在于更新前,則這個可選值包含了舊值,否則它將會是nil
if let oldValue = stringDic.updateValue("3", forKey: "three"){
print("the old value for was \(oldValue)")
}
//還可以使用下標語法來通過給某個鍵的對應值賦值為nil來從字典里移除一個鍵值對
stringDic["four"] = "4";
stringDic["four"] = nil;//“four”對應的鍵值對被移除了
//removeValueForKey(_:)方法也可以用來在字典中移除鍵值對。這個方法在鍵值對存在的情況下會移除該鍵值對并且返回被移除的值或者在沒有值的情況下返回nil
if let removedValue = stringDic.removeValueForKey("three"){
print("The removed name is \(removedValue)");//The removed name is 3
}
//for-in循環來遍歷某個字典中的鍵值對。每一個字典中的數據項都以(key, value)元組形式返回,并且我們可以使用臨時常量或者變量來分解這些元組
for(strCode,stringName) in stringDic{
print("\(strCode):\(stringName)")//one:1 two:2
}
//通過訪問keys或者values屬性,我們也可以遍歷字典的鍵或者值
for strcode in stringDic.keys{
print("strcode = \(strcode)")//strcode = one strcode = two
}
for stringName in stringDic.values{
print("stringName = \(stringName)")// stringName = 1 stringName = 2
}
//Swift 的字典類型是無序集合類型。為了以特定的順序遍歷字典的鍵或值,可以對字典的keys或values屬性使用sort()方法
var stringDic2:[String:String] = ["one":"1","two":"2","three":"3","four":"4","five":"5","six":"6","seven":"7","eight":"8","1":"1","2":"2","3":"3"];
print(stringDic2.values.sort())//["1", "1", "2", "2", "3", "3", "4", "5", "6", "7", "8"],可見輸出結果按升序出來的
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}