【OC】字典(NSDictionary与NSMutableDictionary)

前言

NSDictionary用于保存具有映射关系的数据,故而,NSDictionary保存着两种数值,分别是建和值。

注意
key与value都可以是任意引用类型的数据,Map的key不允许重复。
keyvalue之间存在着一一对应的关系,即通过指定的key,总是可以找到唯一的、确定的value。

key与value之间的关系
在这里插入图片描述

NSDictionary中包含一个allkeys方法,用于返回NSDictionary所有key组成的集合。
但是NSDictionary将allkeys方法返回值设为NSArray——说明该方法经过了进一步转换,已经将NSSet集合转换为NSArray集合。

NSDictionary的功能与用法

NSDictionary集合由多组key-value对组成,故而创建NSDictionary时需要同时指定多组key、value对。下面是创建NSDictionary对象的几种常见方法:
在这里插入图片描述
当得到NSDictionary方法之后,就可以通过方法来访问该集合包括的key-value对的数量。
NSDictionary提供了如下常用的方法:
在这里插入图片描述在这里插入图片描述
为了能直接看到NSDictionary中包含的key-value对的详情,程序为NSDictionary扩展了一个print类别,在该类别中为NSDictionary扩展了一个print方法,用于打印NSDictionary中的key-value详情。
接口部分

#import <Foundation/Foundation.h>

@interface NSDictionary (print)
-(void) print;
-(id) say: (NSString*) word;
@end

实现部分

-(void) print
{
    NSMutableString* result = [NSMutableString stringWithString:@"{"];
    for(id key in self) {
        [result appendString:[key description]];
        [result appendString:@"="];
        [result appendString:[self[key]description]];
        [result appendString:@","];
    }
    NSUInteger len = [result length];
    [result deleteCharactersInRange:NSMakeRange(len - 2, 2)];
    [result appendString:@"}"];
    NSLog(@"%@",result);
}

以上程序示范了NSDictionary的两个基本用法,程序可以通过快速枚举来遍历NSDictionary的所有key。除此之外,程序也可以根据key来获取NSDictionary中对应的value。
下面程序示范了NSDictionary的功能

#import <Foundation/Foundation.h>
#import "NSObject+print.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
    //直接使用多个value、key的形式创建NSDictionary对象
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
                [[Person alloc] initWithName:@"Reus" pass:@"123"],@"one",
                [[Person alloc] initWithName:@"Messi" pass:@"234"],@"two",
                [[Person alloc] initWithName:@"HHH" pass:@"345"],@"three",
                [[Person alloc] initWithName:@"WWW" pass:@"456"],@"four",
                [[Person alloc] initWithName:@"jjj" pass:@"567"],@"five",nil];
        [dict print];
        NSLog(@"dict包含的%ld个key—value对", [dict count]);
        NSLog(@"dict所有的key为:%@", [dict allKeys]);
        NSLog(@"<Person[name = Reus,pass = 123]>对应的所有key为:%@",[dict allKeysForObject:[[Person alloc] initWithName:@"Reus" pass:@"123"]]);
        //获取遍历dict所有value的枚举器
        NSEnumerator* en = [dict objectEnumerator];
        NSObject* value;
        while(value = [en nextObject]) {
            NSLog(@"%@", value);
        }
        //使用指定代码块来迭代执行该集合中的所有key-value对
        [dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL*stop)
         {
            NSLog(@"key的值为:%@",key);
            [value say:@"哇哈哈"];
        }];
    }
    return 0;
}

对NSDictionary的key排序

NSDictionary提供了方法对NSDictionary的所有key进行排序,这些方法执行完成后将返回排序完成后的所有key组成的NSArray。NSDictionary提供的排序方法如下:
在这里插入图片描述

示例程序

#import <Foundation/Foundation.h>
#import "NSObject+print.h"
//#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
                              @"Reus", @"one",
                              @"Messi",@"two",
                              @"HHH",@"three",
                              @"WWW" ,@"four",nil];
        [dict print];
        NSArray* keyArr1 = [dict keysSortedByValueUsingSelector:@selector(compare:)];
        NSArray* keyArr2 = [dict keysSortedByValueUsingComparator:^(id value1, id value2) {
            if([value1 length] > [value2 length]) {
                return NSOrderedDescending;
            }
            if([value1 length] < [value2 length]) {
                return NSOrderedAscending;
            }
            return NSOrderedSame;
        }];
        NSLog(@"%@",keyArr2);
        [dict writeToFile:@"mydict.txt" atomically:YES];
    }
    return 0;
}

运行结果
在这里插入图片描述

对NSDictionary的key进行过滤

NSDictionary提供了方法对NSDictionary的所有key执行过滤,这些方法执行完成后返回满足过滤条件的key组成的NSSet。
NSDictionary提供的过滤方法
在这里插入图片描述
示例程序

#import <Foundation/Foundation.h>
#import "NSObject+print.h"
//#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithInt:89],@"Object-C",
                              [NSNumber numberWithInt:69],@"RUby",
                              [NSNumber numberWithInt:75],@"Python",
                              [NSNumber numberWithInt:109],@"Perl",nil];
        [dict print];
        //对NSDictionary的所有key进行过滤
        NSSet* keySet = [dict keysOfEntriesPassingTest:
        ^(id key, id value, BOOL* stop) {
        //当value的值大于80时返回YES
        //意味着只有value的值大于80才会被保存下来
            return (BOOL)([value intValue] > 80);
        }];
        NSLog(@"%@", keySet);
    }
    return 0;
}

运行结果
在这里插入图片描述

上面程序保留了两个key:Perl和Object-C,他们对应的value分别为109和89,两个value都大于80,因此这两个key可以被保留下来。

使用自定义类作为NSDictionary的key

前面介绍NSDictionary的功能与用法,都是使用NSString作为NSDictionary的key。如果程序打算使用自定义的类作为NSDictionary的key,则该自定义类必须满足以下要求:
在这里插入图片描述
在这里插入图片描述
Person实现的copyWithZone:的方法如下:

-(id) copyWithZone:(NSZone *)zone
{
    NSLog(@"---正在复制---");
    //复制一个对象
    Person* newPerson = [[[self class] allocWithZone:zone]init];
    //将被复制的对象的实变量的值赋给新对象的实例变量
    newPerson->name = name;
    newPerson->pass = pass;
    return newPerson;
}

测试程序

#import <Foundation/Foundation.h>
#import "NSObject+print.h"
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person* u1 = [[Person alloc] initWithName:@"bai" pass:@"345"];
        NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
                              @"one",[[Person alloc] initWithName:@"sun" pass:@"123"],
                              @"two",u1,
                              @"three",[[Person alloc] initWithName:@"sun" pass:@"123"],
                              @"four",[[Person alloc] initWithName:@"tang" pass:@"178"],
                              @"five",[[Person alloc] initWithName:@"niu" pass:@"155"],nil];
        u1.pass = nil;
        //由于NSDictionary并未直接使用u1所指向的Person作为key
        //而是先复制了u1所指向的对象的副本,然后以该副本作为key
        //因此程序将可以看到dict的key不会受到任何影响
        [dict print];
    }
    return 0;
}

NUMutableDictionary的功能与用法

NSMutableDictionary继承了NSDictionary,代表一个key-value可变的NSDictionary集合。由于NSMutableDictionary可以动态的添加key-value对,故而,创建NSMutableDictionary集合时可以指定初始容量
NUSMutableDictionary新增的方法
在这里插入图片描述
示例程序

#import <Foundation/Foundation.h>
#import "NSObject+print.h"
//#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
                                           [NSNumber numberWithInt:89],@"Reus",nil];
        //使用下标法设置key-value对。由于NSDictionary中已经存在该key
        //故而此处设置的value会覆盖前面的value
        dict[@"Reus"] = [NSNumber numberWithInt:99];
        [dict print];
        NSLog(@"--再次添加key-value对--");
        dict[@"Haland"] = [NSNumber numberWithInt:69];
        [dict print];
        NSDictionary* dict2 = [NSDictionary dictionaryWithObjectsAndKeys:
                               [NSNumber numberWithInt:79],@"Messi",
                               [NSNumber numberWithInt:89],@"Jee",nil];
        //将另一个NSDictionary中的key-value对添加到当前NSDictionary中
        [dict addEntriesFromDictionary:dict2];
        [dict print];
        //依据key来删除key-value对
        [dict removeObjectForKey:@"Jee"];
        [dict print];
    }
    return 0;
}

运行结果
在这里插入图片描述

  • 25
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值