字典
前言
NSDictionary
用于保存具有映射关系的数据,故而,NSDictionary保存着两种数值,分别是建和值。
注意:
key与value都可以是任意引用类型的数据,Map的key不允许重复。
key
与value
之间存在着一一对应的关系,即通过指定的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;
}
运行结果: