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阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容