//swift 提供三種集合類型 來(lái)存儲(chǔ)集合數(shù)據(jù)
/*
Array Sets Dictionaries
數(shù)組 array 時(shí)有序數(shù)據(jù)的集津坑,
集合Sets 是無(wú)序無(wú)重復(fù)數(shù)據(jù)的集
字典 dictionary 是無(wú)序的鍵值對(duì)的集
在存儲(chǔ)數(shù)據(jù)時(shí)沈矿,對(duì)數(shù)據(jù)值得類型明確姨拥,不能把不正確的值插入其中遥皂,我們對(duì)取回的值的類型完全自信
如果將集合用變量分配梳杏,那集合就會(huì)是可變的佣耐,我們就可以添加和刪除
如果是常量比然,那就是不可編輯的集合页藻,內(nèi)容背稼,大小都不能改變
*/
/*
數(shù)組Arrays 數(shù)組使用有序列表存儲(chǔ)同一類型的多個(gè)值贰军,相同的值可以多次出現(xiàn)在一個(gè)數(shù)組的不同位置
Swift中 Array 類型被橋接到 Foundation 中的 NSArray類,
Swift 應(yīng)該遵循 Array<Element>其中 Element 是這個(gè)數(shù)組中唯一允許存在的數(shù)據(jù)類型 蟹肘。
也可以使用語(yǔ)法糖词疼,[Element] 這樣的簡(jiǎn)單語(yǔ)法,推薦語(yǔ)法糖來(lái)寫(xiě)
*/
//創(chuàng)建一個(gè)空數(shù)組
var someInts = [Int]()
print("someInts has \(someInts.count) items")
//someInts 被推斷值為Int類型的集合
someInts.append(3)
//此時(shí)數(shù)組中增加了一個(gè)元素 好比oc 的 addobject
print(someInts)
someInts = []//設(shè)置數(shù)組為空 但someints 仍是Int類型的集合
print(someInts)
//swift 還提供一個(gè)可以創(chuàng)建特定大小并且所有數(shù)據(jù)都被默認(rèn)的構(gòu)造方法帘腹,我們可以吧準(zhǔn)備加入新數(shù)組的數(shù)據(jù)項(xiàng)數(shù)量(count)贰盗,和適當(dāng)類型的初始值(repeating)傳入數(shù)組構(gòu)造函數(shù)
var threedoubles = Array(repeating: 0.0, count: 3)
print(threedoubles)
//通過(guò)兩個(gè)數(shù)組相加創(chuàng)建一個(gè)數(shù)組
var testarr = [Any]()//不能寫(xiě)成 []()或 [] 在oc中可以 不確定類型用Any
// var newarr = threedoubles + testarr 報(bào)錯(cuò) 說(shuō)testarr 不確定類型的數(shù)組
var doublearr = [1.1,1.2,1.3]
var newarr = threedoubles + doublearr
print(newarr)//打印輸出結(jié)果 [0.0, 0.0, 0.0, 1.1000000000000001, 1.2, 1.3] 為什么會(huì)有1.100001?
// Decimal
var test1 = [Decimal](repeating: 0.1, count: 3)
var test = [Decimal]()
test = [1.1,1.2,1.3]
print(test)
//也可以這么寫(xiě) stringarr 被聲明為字符串值類型的數(shù)組阳欲,記為[string] 因此這個(gè)數(shù)組被規(guī)定只有string 一種數(shù)據(jù)類型結(jié)構(gòu)舵盈,所以只有string 類型可以在其中被存取陋率,在這里,stringarr由兩個(gè)數(shù)組字面量定義
var stringarr : [String] = ["hello","world"]
//由于swift 的類型推斷機(jī)制秽晚,當(dāng)我們用字面量構(gòu)造只擁有相同類型值數(shù)的時(shí)候瓦糟,我們不必把數(shù)組的類型定義清除。
//只要初始的數(shù)組內(nèi)所有的元素都是同一類型赴蝇,那就該數(shù)組就會(huì)被推斷為同一的類型數(shù)組
//訪問(wèn)數(shù)組 修改數(shù)組
// .count 訪問(wèn)數(shù)組個(gè)數(shù) 與oc一樣
//用isEmpty 來(lái)判斷是否為空數(shù)組
if stringarr.isEmpty{
print("空數(shù)組")
}else{
print("非空數(shù)組")
}
//與string 一樣 用append 來(lái)追加和添加新數(shù)據(jù)項(xiàng)
stringarr.append("hello")
stringarr.append(contentsOf: ["666","777"]) //果然猜的沒(méi)錯(cuò) 就是這么添加另一個(gè)數(shù)組
// stringarr.append(contentsOf: [1.1,2.2]) 報(bào)錯(cuò) 數(shù)據(jù)類型不對(duì)
print(stringarr)
//另一種追加語(yǔ)法糖
stringarr += ["追加"]
print(stringarr)
// stringarr -= ["追加"] 報(bào)錯(cuò) -= 不能用在兩個(gè)數(shù)組中
// print(stringarr)
//追加 不能用下標(biāo)訪問(wèn)的形式去愛(ài)在數(shù)組尾部追加新項(xiàng)
//獲取數(shù)組某一數(shù)據(jù)項(xiàng) 與oc 一樣用下標(biāo)方式
var firstone = stringarr[0] //獲取第一個(gè)數(shù)據(jù)項(xiàng)
print(firstone)
for 字符串 in stringarr{
print(字符串,terminator:"-")
}
//取一個(gè)范圍內(nèi)的數(shù)據(jù)項(xiàng)
var arr = stringarr[2...4]
print(arr)
//插入數(shù)據(jù)項(xiàng) 用insert(_: at:)在某個(gè)具體的索引之前添加數(shù)據(jù)項(xiàng)
stringarr.insert("end", at: stringarr.count)//在個(gè)數(shù)之后追加 沒(méi)問(wèn)題
print(stringarr)
// stringarr.count == stringarr.endIndex 刪除不能用count 和 endindex 下標(biāo)
stringarr.remove(at: stringarr.endIndex-1)//在個(gè)數(shù)之后刪除 會(huì)越界菩浙,下標(biāo)為個(gè)數(shù)的地方?jīng)]有值 超出了下標(biāo)最大值
print(stringarr)
//在操作數(shù)組時(shí),應(yīng)該確保數(shù)組的有效性 數(shù)據(jù)項(xiàng)被移除后數(shù)組的空出項(xiàng)會(huì)被自動(dòng)填補(bǔ)
//如果移除數(shù)組的最后一項(xiàng) 不應(yīng)該用 remoe at 應(yīng)該用removeLast()
stringarr.removeLast()//移除最后一個(gè)
stringarr.removeFirst()//移除第一個(gè)
//數(shù)組的遍歷 使用for in 來(lái)遍歷數(shù)據(jù)項(xiàng)
//如果我們同時(shí)需要每個(gè)數(shù)據(jù)項(xiàng)的值和索引值 可以使用enumerated()方法來(lái)進(jìn)行數(shù)組遍歷.
//enumerated() 返回一個(gè)每一個(gè)數(shù)據(jù)項(xiàng)索引值和數(shù)據(jù)值組成的元組句伶。就是返回索引和元素
//注意是元組 所以 for 后加 () 括號(hào)里面是 下標(biāo)和值
//在oc中用過(guò)這種方法劲蜻,但不知道會(huì)返回索引 只認(rèn)為是遍歷數(shù)組的一種方式
for(index,value) in stringarr.enumerated(){
print(index,value)
}
//集合 Sets
//用來(lái)存儲(chǔ)相同類型并且沒(méi)有確定順序的值,當(dāng)集合元素順序不重要時(shí)考余,或希望確保每個(gè)元素只出現(xiàn)一次時(shí)可以使用集合而不是數(shù)組
//Swift的Set類型被橋接到Foundation 中的NSSet類
/*集合類型的哈希值
一個(gè)類型為了存儲(chǔ)在集合中先嬉,該類型必須是可哈希化的--也就是說(shuō)楚堤,該類型必須提供一個(gè)方法來(lái)計(jì)算它的哈希值疫蔓。一個(gè)哈希值是Int類型的,相等的對(duì)象哈希值必須相同钾军,比如a==b 那么 a.hashvalue== b.hashvalue
Swift的所有基本類型(比如String,Int,double,bool)默認(rèn)都是哈霄郏化的,可以作為集合的值得類型或者字典的鍵的類型吏恭。沒(méi)有關(guān)聯(lián)值得枚舉成員值(在枚舉有講述)默認(rèn)也是可哈限中。化的
*/
/*
你可以使用你自定義的類型作為集合的值得類型 或者是字典的鍵的類型,但你需要使你的自定義的類型符合Swift標(biāo)準(zhǔn)庫(kù)中的hashable協(xié)議樱哼。符合hashable協(xié)議的類型需要提供一個(gè)類型為Int的可讀屬性hashvalue哀九。由類型的hashvalue屬性返回的值不需要在同一程序的不同執(zhí)行周期或者不同程序之間保持相同。
*/
/*
因?yàn)閔ashable協(xié)議符合Equatable協(xié)議搅幅。所以遵循該協(xié)議的類型也必須提供一個(gè)“是否相等”運(yùn)算符==的實(shí)現(xiàn)阅束,這個(gè)Equatable協(xié)議要求任何符合 == 實(shí)現(xiàn)的實(shí)例間都是一種相等的關(guān)系。也就是說(shuō)茄唐,對(duì)于abc三個(gè)值來(lái)說(shuō) == 的實(shí)現(xiàn)必須滿足下面三種情況
*/
/*
a == a 自反性
a == b 意味著 b == a 對(duì)稱性
a == b && b == c 意味著 a == c
*/
/*
集合類型語(yǔ)法
Swift 中的Set類型被寫(xiě)為Set<element> 這里的element 表示Set中允許存儲(chǔ)的類型息裸,和數(shù)組不同的是,集合沒(méi)有等價(jià)的簡(jiǎn)化形式沪编。md 就是沒(méi)有語(yǔ)法糖唄呼盆,還沒(méi)有等價(jià)的簡(jiǎn)化形式,不仔細(xì)想想都tm看不懂說(shuō)的啥蚁廓。
*/
var letters = Set<Character>()//空的集合
// var settest : Set = [Character]() 報(bào)錯(cuò)說(shuō)不能轉(zhuǎn)化為值類型在 Set上 說(shuō)明語(yǔ)法糖不能用
print("letters is of type Set<character> with \(letters.count)")
//根據(jù)上下文提供了類型信息访圃,比如作為函數(shù)的參數(shù)或者已知類型的變量或常量,我們可以通過(guò)一個(gè)空的數(shù)組字面量創(chuàng)建一個(gè)空的set
letters.insert("a")
print(letters)
let has = 1
// letters.insert(has.hashValue) 試試行不行 因?yàn)橐呀?jīng)定義為character類型的集合了
letters = [] //這樣才可以用語(yǔ)法糖置空相嵌,因?yàn)橐呀?jīng)明確了類型
print(letters)
//用數(shù)組字面量創(chuàng)建集合
//可以使用數(shù)組字面量來(lái)構(gòu)造集合腿时,并且可以使用簡(jiǎn)化形式寫(xiě)一個(gè)或者多個(gè)值多為集合元素
//構(gòu)造一個(gè)含有初始值的集合
var stringSet : Set<String> = ["hello","world","!"]
//一個(gè)set類型不能從數(shù)組字面量中被單獨(dú)推斷出來(lái)况脆,因此set類型必須為顯示聲明,然而批糟,由于Swift的類型推斷功能格了,如果你想使用一個(gè)數(shù)組字面量構(gòu)造一個(gè)set并且該數(shù)組字面量中的所有元素類型相同,那么就可以不用寫(xiě)出set的具體類型
var notype : Set = ["a","b","c"]//不能使用語(yǔ)法糖是錯(cuò)的 要加上指定的類型 set 后面才可以用語(yǔ)法糖
notype.isEmpty //是否為空
notype.count //個(gè)數(shù)
notype.insert("insert") //插入一個(gè)元素 不是數(shù)組 沒(méi)有需要下標(biāo)
print(notype)
notype.removeFirst()//刪除第一個(gè)
print(notype)
// notype.removeAll()//刪除所有
notype.removeAll(keepingCapacity: true)//有啥用跃赚? 我以為是刪除后笆搓,保留刪除前的所有元素開(kāi)辟的空間性湿,只是值不在了纬傲。更具arrayviewcapacity來(lái)看也是自動(dòng)釋放的意思
print(notype,notype.count)
var notype1 : Set = ["a","b","c"]
//通過(guò)刪除一個(gè)元素,如果該值時(shí)set的一個(gè)元素則刪除該元素肤频,并且返回被刪除的元素叹括。如果set不包含則返回nil
if let removed = notype1.remove("a"){
print(removed,"移除a")
}else{
print("沒(méi)有匹配任何值")
}
if notype1.contains("b"){
print("包含元素")
}else{
print("不包含")
}
for item in notype1{
print("\(item)")
}
let newSet : Set = ["1","2","3","4"]
let oldSet : Set = ["3","4","5","6"]
//取相同
let same = newSet.intersection(oldSet)
print(same)
//取除相同之外
let nosame = newSet.symmetricDifference(oldSet)
print(nosame)
//去重復(fù)
let quchong = newSet.union(oldSet)
print(quchong)
//取出除另一個(gè)所有
let noOther = newSet.subtracting(oldSet)
print(noOther)
//取出后的新集合是無(wú)序的
//只需在括號(hào)后 加 .sorted() 進(jìn)行排序
let union = newSet.union(oldSet).sorted()
print(union)
//判斷一個(gè)集合的值是否也在另一個(gè)集合中包含
//事實(shí)上 a只有部分被b包含 所以不行
if newSet.isSubset(of: oldSet){
print("a在b包含")
}else{
print("a不被b包含")
}
let a : Set = ["1","1"]
let b : Set = ["1","1","2","2"]//包含a
// let b : Set = ["1","2","2"]//包含a
if a.isSubset(of: b){
print("a在b包含")
}else{
print("a不被b包含")
}
//翻譯的不明確,應(yīng)為一個(gè)集合中的所有元素 都在另一個(gè)集合中出現(xiàn)過(guò)宵荒,可以用 isSubset(of:)
//一個(gè)集合是否完全包含另一個(gè)b
if a.isSuperset(of: b){
print("a完全包含b")
}else{
print("a不完全包含b")
}
let c : Set = ["2","3","4"]
//使用 isStrictSubset(of:) isStrictSuperset(of:) 來(lái)判斷一個(gè)集合是否是另一個(gè)集合的自己和或父集合 并且兩個(gè)集合不相等
let q : Set = ["1","2"]
let w : Set = ["1","2"]
print(q.isSubset(of: w))//q是否被w包含 true
print(q.isSuperset(of: w))//q 是否包含w true
print(q.isStrictSubset(of: w))//q是否是w 的子集合 false
print(q.isStrictSuperset(of: w))//q是否是w的父集合 false
let x : Set = ["1","2"]
let y : Set = ["1","2","3"]
print(x.isSubset(of: y))//q是否被w包含 true
print(x.isSuperset(of: y))//q 是否包含w false
print(x.isStrictSubset(of: y))//q是否是w 的子集合 true
print(x.isStrictSuperset(of: y))//q是否是w的父集合 false
//使用isDisjoint(with:) 來(lái)判斷兩個(gè)集合是否不包含有相同的值(是否沒(méi)有交集)
//字典 Swift的Dictionary 類型被橋接到Oc 的 NSDictionary類
//一個(gè)字典的key 必須遵循h(huán)ashable協(xié)議 就想Set的值類型
//定義時(shí)汁雷,可以用dictionary<key,Value> 或者 語(yǔ)法糖 [key:value]
//創(chuàng)建一個(gè)空字典
var dict = [Int : String]()
dict = [1:"1",2:"2"]
print(dict)
//其中 4 是key 非下標(biāo)
dict[4] = "2" //沒(méi)有使用增加方法 ,直接指定一個(gè)key設(shè)置上值 就新增了一個(gè)鍵值對(duì)
print(dict)
//在定義的時(shí)候不能用[:] 置為空的時(shí)候可以使用
dict = [:]
print(dict)
var airport : [String : String] = ["where":"beijing","money":"1000"]
//如果在構(gòu)造字典時(shí) 如果每個(gè)值 或者 每個(gè)鍵 都是同一類型 就不需要定義類型
//使用isEmpty 來(lái)檢查count 是否為0
//使用count 來(lái)獲取字典的數(shù)據(jù)項(xiàng)個(gè)數(shù)
airport["haha"] = "xixi" //指定某個(gè)鍵為某個(gè)值
print(airport)
airport["where"] = "上海" //通過(guò)key來(lái)修改該key所對(duì)應(yīng)的值
//作為另一種下標(biāo)方法报咳,字典的updatevalue(_:forkey:) 方法可以設(shè)置或者更新特定鍵對(duì)應(yīng)的值侠讯。就想上面所示的下標(biāo)示例,updatevalue(_:forkey:)方法在這個(gè)鍵不存在對(duì)應(yīng)值得時(shí)候會(huì)設(shè)置新值或者在存在時(shí)更新已存在的值,和上面的下標(biāo)方法不同的暑刃,updatevalue(_:forkey:)這個(gè)方法返回更新值之前的原值厢漩,這樣使得我們可以檢查更新是否成功
//updatevalue 方法會(huì)返回對(duì)應(yīng)值得類型的可選值 對(duì)于存儲(chǔ)string 值得字典,這個(gè)函數(shù)會(huì)返回一個(gè)string岩臣? 或者 可選string類型的值
//如果有值存在于更新前溜嗜,則這個(gè)可選值包含了舊值,否則它將會(huì)是nil
if let oldvalue = airport.updateValue("haha", forKey: "haha"){
print("oldvalue is \(oldvalue)") //執(zhí)行 有 haha key 返回haha 之前的值
}else{
print("nil")
}
print(airport["lala"])//訪問(wèn)該key對(duì)應(yīng) 的值架谎,若key對(duì)應(yīng)的值不存在 返回nil
if let newvalue = airport.updateValue("haha", forKey: "lala"){
print("oldvalue is \(newvalue)")
}else{
print("nil") //執(zhí)行 因?yàn)闆](méi)有l(wèi)ala 這個(gè)key
}
//removevalue(forkey:)方法也可以用來(lái)在字典中移除鍵值對(duì),這個(gè)方法在鍵值對(duì)存在的情況下會(huì)移除該鍵值對(duì)并且返回被移除的值或者在沒(méi)有值的情況下返回nil
if let value = airport.removeValue(forKey: "money"){
print(value) //執(zhí)行 有money key 返回money key之前的值
}else{
print("no key money")
}
print(airport)
//字典遍歷
var json = ["1":"one","2":"two","3":"three","4":"four","5":"five"]
for (jsonkey,jsonvalue) in json{
print("\(jsonkey),\(jsonvalue)")
}
for key in json.keys{
print(key)
}
for value in json.values{
print(value)
}
//swift 的字典類型是無(wú)序的的集合類型 炸宵。為了以特定的順序遍歷字典的鍵或值,可以對(duì)字典的keys或者values屬性使用Sorted()方法
for sortedkey in json.keys.sorted(){
print(sortedkey)
}
for sortedvalue in json.values.sorted(){
print(sortedvalue)
}
var jsonChinese = ["安徽":"one","重慶":"two","安陽(yáng)":"three","蚌埠":"four","支付寶":"five"]
for sortedkey in jsonChinese.keys{
print(sortedkey)
}
for sortedvalue in jsonChinese.keys.sorted(){
print(sortedvalue)
}
//然而對(duì)中文并沒(méi)有什么亂用 白高興一場(chǎng) 如果key是英文的話 會(huì)按英文的字母順序來(lái)排
輸出為
someInts has 0 items
[3]
[]
[0.0, 0.0, 0.0]
[0.0, 0.0, 0.0, 1.1000000000000001, 1.2, 1.3]
[1.1, 1.2, 1.3]
非空數(shù)組
["hello", "world", "hello", "666", "777"]
["hello", "world", "hello", "666", "777", "追加"]
hello
hello-world-hello-666-777-追加-["hello", "666", "777"]
["hello", "world", "hello", "666", "777", "追加", "end"]
["hello", "world", "hello", "666", "777", "追加"]
0 world
1 hello
2 666
3 777
letters is of type Set<character> with 0
["a"]
[]
["b", "insert", "a", "c"]
["insert", "a", "c"]
[] 0
a 移除a
包含元素
b
c
["3", "4"]
["2", "1", "6", "5"]
["4", "2", "1", "5", "6", "3"]
["2", "1"]
["1", "2", "3", "4", "5", "6"]
a不被b包含
a在b包含
a不完全包含b
true
true
false
false
true
false
true
false
[2: "2", 1: "1"]
[2: "2", 4: "2", 1: "1"]
[:]
["money": "1000", "haha": "xixi", "where": "beijing"]
oldvalue is xixi
nil
nil
1000
["haha": "haha", "where": "上海", "lala": "haha"]
4,four
2,two
1,one
5,five
3,three
4
2
1
5
3
four
two
one
five
three
1
2
3
4
5
five
four
one
three
two
安陽(yáng)
支付寶
蚌埠
安徽
重慶
安徽
安陽(yáng)
支付寶
蚌埠
重慶