swift簡單總結(十三)—— 集合類型之字典

版本記錄

版本號 時間
V1.0 2017.07.25

前言

我是swift2.0的時候開始接觸的,記得那時候還不是很穩定,公司的項目也都是用oc做的,并不對swift很重視,我自己學了一段時間,到現在swift3.0+已經出來了,自己平時也不寫,忘記的也差不多了,正好項目這段時間已經上線了,不是很忙,我就可以每天總結一點了,希望對自己對大家有所幫助。在總結的時候我會對比oc進行說明,有代碼的我會給出相關比對代碼。
1. swift簡單總結(一)—— 數據簡單值和類型轉換
2. swift簡單總結(二)—— 簡單值和控制流
3. swift簡單總結(三)—— 循環控制和函數
4. swift簡單總結(四)—— 函數和類
5. swift簡單總結(五)—— 枚舉和結構體
6. swift簡單總結(六)—— 協議擴展與泛型
7. swift簡單總結(七)—— 數據類型
8. swift簡單總結(八)—— 別名、布爾值與元組
9. swift簡單總結(九)—— 可選值和斷言
10. swift簡單總結(十)—— 運算符
11. swift簡單總結(十一)—— 字符串和字符
12. swift簡單總結(十二)—— 集合類型之數組

字典

字典是一種可以存儲多個相同類型值的容器,每個值value都關聯唯一的鍵key,存儲在字典中的數據沒有具體順序,可以像查字典一樣根據具體的key找到唯一對應的value

不同的是:

  • swift的字典使用時需要具體規定可以存儲的鍵和值類型,oc 中的NSMutableDictionaryNSDictionary類可以使用任何類型的對象作為鍵和值,并且不會提供任何關于這些對象的本質信息。
  • swift中在某個特定字典中可以存儲的鍵和值必須提前定義清楚,方法就是通過顯性類型或者類型推斷。

swift的字典使用Dictionary<keyType, valueType>定義,其中keyType就是鍵,valueType就是鍵對應的值,這里keyType的唯一限制就是可哈希的,這樣可以保證它是獨一無二的,所有的swift基本類型(StringIntDoubleBool)都是默認可哈希的,未關聯的枚舉成員也是默認可哈希的,所以他們都可以作為鍵使用。

1. 字典字面量

可以使用字典字面量構造字典,字典中的鍵值之間用冒號:分隔,相鄰的鍵值對之間用逗號,隔開,下面看swift中的例子。

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong"]
    print(cityDict)

下面看輸出結果

["JiNan": "ShanDong", "HaErbin": "HeiLongJiang"]

像上面這么定義,就表示這個字典的鍵和值的類型都是String

如果我們使用字面量構造字典就不用把類型定義清楚,cityDict也可以像下面這么定義。

 var cityDict = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong"]

下面我們看一下oc中的字典字面量的定義方法。

    NSDictionary *cityDict = @{@"HaErbin" : @"HeiLongJiang", @"JiNan" : @"ShanDong"};
    NSLog(@"%@",cityDict);

下面看輸出結果

2017-07-25 13:29:33.193621+0800 JJOC[5255:1660727] {
    HaErbin = HeiLongJiang;
    JiNan = ShanDong;
}

2. 讀取和修改字典

我們可以和數組一樣,通過方法屬性或者下標語法讀取和修改字典的值。

獲取某個字典的數據量

我們先看一下swift

var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
print("\(cityDict.count)")

下面看輸出結果

3

下面我們在看一下oc中字典字面量的定義。

    NSDictionary *cityDict = @{@"HaErbin" : @"HeiLongJiang", @"JiNan" : @"ShanDong", @"HaiKou" : @"HaiNan"};
    NSLog(@"%d",cityDict.count);

下面看輸出結果

2017-07-25 13:50:50.071943+0800 JJOC[5261:1662977] 3

獲取字典是否為空

下面我們看一下swift中字典是否為空的判斷

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    if cityDict.isEmpty {
        print("YES")
    }
    else {
        print("NO")
    }

下面我們就看輸出結果

NO

可見,和數組一樣,字典也有這個isEmpty屬性。

下面我們就看一下oc中的情況

    NSDictionary *cityDict = @{@"HaErbin" : @"HeiLongJiang", @"JiNan" : @"ShanDong", @"HaiKou" : @"HaiNan"};
    if (cityDict.count == 0) {
        NSLog(@"YES");
    }
    else {
        NSLog(@"NO");
    }

下面看輸出結果

2017-07-25 13:56:35.741471+0800 JJOC[5265:1663910] NO

增加字典中的值

我們可以增加字典中對應的值,我們先看一下swift中的情況。

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    cityDict["NanJing"] = "JiangSu"
    print(cityDict)

下面看輸出結果

["HaiKou": "HaiNan", "HaErbin": "HeiLongJiang", "NanJing": "JiangSu", "JiNan": "ShanDong"]

接著看oc中的情況

    NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"HeiLongJiang", @"HaErbin" ,@"ShanDong", @"JiNan" ,@"HaiNan", @"HaiKou" , nil];
    [dictM setObject: @"LiaoNing" forKey:@"ShenYang"];
    NSLog(@"%@",dictM);

下面看輸出結果

2017-07-25 14:30:28.030160+0800 JJOC[5279:1668883] {
    HaErbin = HeiLongJiang;
    HaiKou = HaiNan;
    JiNan = ShanDong;
    ShenYang = LiaoNing;
}

更改字典中的值

下面我們看一下如何更改字典中的值。

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    cityDict["HaErbin"] = "HeiLongJiang1"
    print(cityDict)

下面看輸出結果

["JiNan": "ShanDong", "HaiKou": "HaiNan", "HaErbin": "HeiLongJiang1"]

還可以用updateValue方法設置或者更新特定鍵對應的值,該方法在這個鍵不存在對應值的時候設置值或者在存在時更新已存在的值,這個方法會有返回值,返回的是更新后的原值。像這個例子中,如果存在該鍵對應的值,就會返回被替換的值,如果不存在那么返回nil

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    if let oldValue = cityDict.updateValue("HeiLongJiang1", forKey: "HaErbin") {
        print("The old value is \(oldValue)")
    }
    print(cityDict)

看輸出結果

The old value is HeiLongJiang
["JiNan": "ShanDong", "HaiKou": "HaiNan", "HaErbin": "HeiLongJiang1"]

下面我們看oc中的情況

    NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"HeiLongJiang", @"HaErbin" ,@"ShanDong", @"JiNan" ,@"HaiNan", @"HaiKou" , nil];
    [dictM setObject:@"HeiLongJiang1" forKey:@"HaErbin"];
    NSLog(@"%@",dictM);

下面看輸出結果

2017-07-25 14:35:43.640693+0800 JJOC[5283:1669849] {
    HaErbin = HeiLongJiang1;
    HaiKou = HaiNan;
    JiNan = ShanDong;
}

字典值的檢索

下面我們先看一下swift中字典的檢索。可以用下標語法來檢索某一個鍵對應的值,由于可能存在沒有值的鍵,因此可選類型返回這個鍵存在的值,否則返回nil

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
        
    if let province = cityDict["HaErbin"] {
        print("The Province is \(province)")
    }
    else {
        print("The Province does not exists")
    }

下面看輸出結果

The Province is HeiLongJiang

下面我們就看一下oc中字典的檢索。

    NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"HeiLongJiang", @"HaErbin" ,@"ShanDong", @"JiNan" ,@"HaiNan", @"HaiKou" , nil];
    if ([dictM objectForKey:@"HaErbin"]) {
        NSLog(@"The Province is %@", [dictM objectForKey:@"HaErbin"]);
    }
    else {
        NSLog(@"The Province does not exists");
    }

下面看輸出結果

2017-07-25 14:53:33.954069+0800 JJOC[5290:1672055] The Province is HeiLongJiang

字典移除鍵值對

下面我們先看一下swift中如何移除某個鍵值對,一種方法就是通過將某個鍵對應的值賦值為nil來從字典里刪除這個鍵值對。

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang1", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    cityDict["HaErbin"] = nil
    print(cityDict)

下面我們看輸出結果

["JiNan": "ShanDong", "HaiKou": "HaiNan"]

還有就是通過removeValue方法移除某一個鍵值對,該方法在鍵值對存在的情況下會刪除該鍵值對并返回被移除的值,在鍵值不存在的情況下返回nil,看下面的例子。

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang1", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    if let removeValue = cityDict .removeValue(forKey: "HaErbin"){
        print(removeValue)
    }
    else {
        print("does not exists a value For this key")
    }
     print(cityDict)

下面看輸出結果

HeiLongJiang1
["JiNan": "ShanDong", "HaiKou": "HaiNan"]

下面我們看一下oc中的鍵值對的移除。

    NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"HeiLongJiang", @"HaErbin" ,@"ShanDong", @"JiNan" ,@"HaiNan", @"HaiKou" , nil];
    [dictM removeObjectForKey:@"HaErbin"];
    NSLog(@"%@",dictM);

下面看輸出結果

2017-07-25 15:10:33.523594+0800 JJOC[5299:1674259] {
    HaiKou = HaiNan;
    JiNan = ShanDong;
}

ocswift中都可以調用removeAllObjects移除所有的鍵值對。

3. 字典的遍歷

先看一下swift中字典的遍歷,一種方法就是利用for - in完成遍歷。每一個字典的數據都是通過 (key, value)元組的形式返回。并且可以使用臨時常量或者變量來分解這些元組。

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    for (city, province) in cityDict {
        print("\(city) in \(province)")
    }

下面看輸出結果

JiNan in ShanDong
HaiKou in HaiNan
HaErbin in HeiLongJiang

也可以通過keys或者values屬性檢索一個字典的鍵或者值。

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    for city in cityDict.keys {
        print(city)
    }
        
    print("--------")
        
    for province in cityDict.values {
        print(province)
    }

看輸出結果

JiNan
HaiKou
HaErbin
--------
ShanDong
HaiNan
HeiLongJiang


還可以用下面的方式Array的方法獲取數組。

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    let cityKeys = Array(cityDict.keys)
    let cityValues = Array(cityDict.values)
    print(cityKeys)
    print(cityValues)

看輸出結果

["JiNan", "HaiKou", "HaErbin"]
["ShanDong", "HaiNan", "HeiLongJiang"]

接著看一下oc中利用for - in的遍歷

    NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"HeiLongJiang", @"HaErbin" ,@"ShanDong", @"JiNan" ,@"HaiNan", @"HaiKou" , nil];
    for (NSString *key in dictM.allKeys) {
        NSLog(@"%@",key);
    }
    
    NSLog(@"--------");
    
    for (NSString *value in dictM.allValues) {
        NSLog(@"%@",value);
    }

下面看輸出結果

2017-07-25 15:23:30.646094+0800 JJOC[5308:1676982] HaErbin
2017-07-25 15:23:30.646142+0800 JJOC[5308:1676982] JiNan
2017-07-25 15:23:30.646157+0800 JJOC[5308:1676982] HaiKou
2017-07-25 15:23:30.646170+0800 JJOC[5308:1676982] --------
2017-07-25 15:23:30.646187+0800 JJOC[5308:1676982] HeiLongJiang
2017-07-25 15:23:30.646201+0800 JJOC[5308:1676982] ShanDong
2017-07-25 15:23:30.646213+0800 JJOC[5308:1676982] HaiNan

除了for - in遍歷還可以enumerated進行遍歷,先看swift

    var cityDict : [String : String] = ["HaErbin" : "HeiLongJiang", "JiNan" : "ShanDong", "HaiKou" : "HaiNan"]
    for (key, value) in cityDict.enumerated(){
        print("\(key) in \(value)")
    }

下面看輸出結果

0 in ("JiNan", "ShanDong")
1 in ("HaiKou", "HaiNan")
2 in ("HaErbin", "HeiLongJiang")

下面我們就看一下oc中字典的遍歷。

    NSMutableDictionary *dictM = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"HeiLongJiang", @"HaErbin" ,@"ShanDong", @"JiNan" ,@"HaiNan", @"HaiKou" , nil];
    [dictM enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        NSLog(@"%@--%@",key,obj);
    }];

下面看輸出結果

2017-07-25 15:33:30.457579+0800 JJOC[5316:1678783] HaErbin--HeiLongJiang
2017-07-25 15:33:30.457626+0800 JJOC[5316:1678783] JiNan--ShanDong
2017-07-25 15:33:30.457642+0800 JJOC[5316:1678783] HaiKou--HaiNan

注意:字典屬于無序集合類型,其中鍵值對出現的順序是不一定的。

4. 空字典的創建

我們可以像數組一樣構造一個空字典,先看一下swift中的情況。

//這就是一個空字典
var nameDict = Dictionary<Int, String>()

上面創建的就是一個鍵類型為Int,值類型為String的字典。

如果上下文提供了信息類型,我們就可以使用空字典字面量來創建一個空字典,記作[:]

    var nameDict = Dictionary<Int, String>()
    nameDict[1] = "Lily"
    //現在nameDict又成為了一個鍵為Int值為String的空字典了
    nameDict = [:]

下面我們就看一下oc中空字典的實例化

NSMutableDictionary *dictM = [NSMutableDictionary dictionary];

注意:

  • 不管是數組還是字典,空對象實例化都是實例可變對象,如果實例化一個不可變對象,后期又不能往里面加數據,那么空對象毫無意義。
  • 如果字典或者數組后期是不變化的,就盡量實例化成不可變對象,這樣編譯器會進行優化,同時也防止里面的元素被在不知道的情況下更改。

后記

未完,待續~~~

明月
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容