前言
对于Objective-C的初学者来说,字典的概念可能很好理解,但在实际使用中,可能会被字典套数组,数组套字典,字典套字典等情况搞得晕头转向。以下是我在网上找的两个例题,并且给了每一步的相关解析,希望能够加深大家对字典的理解。
例一:
处理⽂件crayons.txt中的⽂本信息,⽂本内容是关于颜⾊的,每⾏都是⼀
个颜⾊的信息,例如:Almond #EED9C4,前⼀个字符串是颜⾊的名称,后⼀个字符串是颜⾊的16进制⾊值,处理⽂本完成如下需求:
使⽤字典管理所有的颜⾊,即字典中存储的是多个键值对,颜⾊名称为 key,16进制颜⾊值(不带#)是value。
使⽤⼀个新的字典管理颜⾊,对颜⾊进⾏分类管理,即:“A”,“B”,“C”… 即这个字典包含多个键值对,key是26个字⺟,value是数组,数组⾥存放的是 Color对象(包含name和colorValue属性,这两个属性都是OC字符串类型)。需要⾃⼰创建Color类。
main.h
int main(int argc, const char * argv[]) {
// 读取文件
NSString *sourceString = [NSString stringWithContentsOfFile:@"/Users/Phelan/Desktop/crayons.txt" encoding:NSUTF8StringEncoding error:nil];
// 通过换行符'\n',将文件分割成独立的每一行
NSArray *lineArray = [sourceString componentsSeparatedByString:@"\n"];
// 创建一个空的可变的字典,key用来存储颜色的名字,value用来存储颜色的值
NSMutableDictionary *colorDic = [NSMutableDictionary dictionary];
// 遍历数组,取出每一个颜色名,和颜色值(需要分割)
for (int i = 0; i < lineArray.count; i++) {
if (![lineArray[i] isEqualToString:@""]) {
// 从数组里取出每一个颜色的信息
NSString *oneColorInfo = lineArray[i];
// 拿到信息后,按照一个空格加井号的形式进行拆分,用一个数组进行接收
// 数组中包含两个颜色,第一个为颜色名,第二个为颜色值
NSArray *infoArray = [oneColorInfo componentsSeparatedByString:@" #"];
// 将拿到的信息保存到字典里
// 注意infoArray[0] 和infoArray[1]会报错的原因
[colorDic setObject:[infoArray lastObject] forKey:[infoArray firstObject]];
}
}
// 创建一个新的空字典
NSMutableDictionary *newDic = [NSMutableDictionary dictionary];
// 根据colorDic字典的长度,依次取出key跟value给Color对象赋值
for (int i = 0; i < colorDic.count; i++) {
// 颜色名
NSString *key = colorDic.allKeys[i];
// 颜色值
NSString *value = colorDic.allValues[i];
// 创建一个Color对象,将这个两个属性赋值
Color *color = [Color colorWithName:key andColorValue:value];
// 根据key取出第一个字母
NSString *firstWord = [key substringToIndex:1];
// 从新创建的空字典里根据第一个字母取值,如果取不出来就创建
// 这样就避免了重复创建数组
NSMutableArray *colorArray = [newDic objectForKey:firstWord];
// 比如此时的Key为A,已经存在,就不在创建,直接添加
if (nil == colorArray) {
colorArray = [NSMutableArray array];
[newDic setObject:colorArray forKey:firstWord];
}
[colorArray addObject:color];
}
NSLog(@"%@", newDic);
return 0;
}
Color.h
#import <Foundation/Foundation.h>
@interface Color : NSObject
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *colorValue;
# pragma mark - init
- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithName:(NSString *)name andColorValue:(NSString *)colorValue;
# pragma mark - handy constructor
+ (instancetype)colorWithName:(NSString *)name;
+ (instancetype)colorWithName:(NSString *)name andColorValue:(NSString *)colorValue;
@end
Color.m
#import "Color.h"
@implementation Color
# pragma mark - init
- (instancetype)init {
return [self initWithName:nil andColorValue:nil];
}
- (instancetype)initWithName:(NSString *)name {
return [self initWithName:name andColorValue:nil];
}
- (instancetype)initWithName:(NSString *)name andColorValue:(NSString *)colorValue {
if ([super init] != nil) {
_name = name;
_colorValue = colorValue;
}
return self;
}
# pragma mark - handy constructor
+ (instancetype)colorWithName:(NSString *)name {
return [[self alloc]initWithName:name andColorValue:nil];
}
+ (instancetype)colorWithName:(NSString *)name andColorValue:(NSString *)colorValue {
return [[self alloc]initWithName:name andColorValue:colorValue];
}
@end
-
控制台打印效果
-
点击下载:crayons.txt
例二:
将附件中的文件按照以下格式分割输出
最外层是数组,数组里的元素是省份字典,包含两个键值对,key是provinceName,value对应省份名,另一个key是cityArray,value是一个城市数组;cityArray里的元素是城市字典,有两个键值对,key是cityName,value是城市名,另一个键值对key是areaArray,value是一个地区数组;在地区数组里存放的是地区字典,key是areaName,value是地区名
main.h
int main(int argc, const char * argv[]) {
// 生成字典格式
NSString *source = [NSString stringWithContentsOfFile:@"/Users/Phelan/Desktop/area.txt" encoding:NSUTF8StringEncoding error:nil];
// 分割每一行字符串
NSArray *lineArray = [source componentsSeparatedByString:@"\n"];
// 创建最外层装所有省份的数组
NSMutableArray *allProvinceArray = [NSMutableArray array];
// 遍历每一行字符串
for (NSString *string in lineArray) {
// 没有@" "前缀的为省名(两个空格)
if (![string hasPrefix:@" "]) {
// 创建省份字典
NSMutableDictionary *provinceDic = [NSMutableDictionary dictionary];
// 设置省名键值对
[provinceDic setObject:string forKey:@"provinceName"];
// 创建该省份对应的城市数组
NSMutableArray *cityArray = [NSMutableArray array];
// 设置城市数组键值对
[provinceDic setObject:cityArray forKey:@"cityArray"];
// 添加到省份数组中
[allProvinceArray addObject:provinceDic];
} else if (![string hasPrefix:@" "]) // 如果没有四个空格
{
// 获取当前的城市名属于哪个省份字典
NSMutableDictionary *provinceDic = [allProvinceArray lastObject];
// 获取当前省份字典中的城市数组
NSMutableArray *cityArray = [provinceDic objectForKey:@"cityArray"];
// 创建一个城市字典
NSMutableDictionary *cityDic = [NSMutableDictionary dictionary];
[cityDic setObject:string forKey:@"cityName"];
// 创建一个地区数组
NSMutableArray *areaArray = [NSMutableArray array];
// 设置地区数组键值对
[cityDic setObject:areaArray forKey:@"areaArray"];
// 将城市字典添加到城市数组中
[cityArray addObject:cityDic];
} else {
// 获取当前的省份字典
NSMutableDictionary *provinceDic = [allProvinceArray lastObject];
// 获取当前省份的城市数组
NSMutableArray *cityArray = [provinceDic objectForKey:@"cityArray"];
// 获取当前城市字典
NSMutableDictionary *cityDic = [cityArray lastObject];
// 获取当前城市的地区数组
NSMutableArray *areaArray = [cityDic objectForKey:@"areaArray"];
// 创建地区字典
NSMutableDictionary *areaDic = [NSMutableDictionary dictionary];
// 设置键值对
[areaDic setObject:string forKey:@"areaName"];
// 将地区字典添加到地区数组中
[areaArray addObject:areaDic];
}
}
// 遍历省份数组
for (NSMutableDictionary *provinceDic in allProvinceArray) {
NSLog(@"省名 : %@" ,[provinceDic objectForKey:@"provinceName"]);
// 遍历城市数组
for (NSMutableDictionary *cityDic in [provinceDic objectForKey:@"cityArray"]) {
NSLog(@"----市名: %@", [cityDic objectForKey:@"cityName"]);
// 遍历地区数组
for (NSMutableDictionary *areaDic in [cityDic objectForKey:@"areaArray"]) {
NSLog(@"--------区名 : %@", [areaDic objectForKey:@"areaName"]);
}
}
}
return 0;
}
- 控制台打印效果
- 对例二深刻理解后,关键部分的代码可以缩减成如下形式
int main {
...
for (NSString *string in [source componentsSeparatedByString:@"\n"]) {
if (![string hasPrefix:@" "]) {
NSMutableArray *cityArray = [NSMutableArray array];
NSMutableDictionary *provinceDic = [NSMutableDictionary dictionaryWithObjects:@[string, cityArray] forKeys:@[@"provinceName", @"cityArray"]];
[allProvince addObject:provinceDic];
}else if (![string hasPrefix:@" "]) {
NSMutableArray *areaArray = [NSMutableArray array];
NSMutableDictionary *cityDic = [NSMutableDictionary dictionaryWithObjects:@[string, areaArray] forKeys:@[@"cityName",@"areaArray"]];
[[[allProvince lastObject] objectForKey:@"cityArray"] addObject:cityDic];
}else{
NSMutableDictionary *areaDic = [NSMutableDictionary dictionaryWithObject:string forKey:@"areaName"];
[[[[[allProvince lastObject] objectForKey:@"cityArray"] lastObject] objectForKey:@"areaArray"] addObject:areaDic];
}
}
...
return 0;
}
- 点击下载:area.txt
网友评论