通讯录解析
1.创建一个联系人类,可以生产联系人,也就是联系人对象
2.创建一个电话簿类,可以把联系人装进去
所以我们需要创建两个类,一个生产联系人,一个对联系人进行包装。怎么包装?通过字典和数组对联系人包装在一起。
用到的知识点
- 字典和数组的嵌套
- 字典和数组的遍历
- NSString类 ,NSMutableArray类,NSMutableDictionary类的一些方法
- 按照类的某个属性(实例变量)排序
通讯录的功能:以下的功能都是电话簿的功能
- 添加联系人
- 按号码查找联系人
- 根据姓名删除联系人
- 获取某个分组下的联系人
- 将联系人按姓名的升序排序
- 显示联系人。
代码的实现:
第一个类的AddressPerson.h文件里面的内容:
#import <Foundation/Foundation.h>
@interface AddressPerson : NSObject
{
// 实例变量
// 姓名
NSString *_name;
// 地址
NSString *_address;
// 邮箱名称
NSString *_email;
// 电话号码
NSInteger _telNumber;
}
// 带参初始化
- (instancetype)initWithName:(NSString *)name
andTelNumber:(NSInteger)telNumber
andEmail:(NSString *)email;
// 实例变量 姓名setter
- (void)setName:(NSString *)name;
// 姓名getter
- (NSString *)name;
// 地址 setter
- (void)setAddress:(NSString *)address;
// 地址 getter
- (NSString *)address;
// 邮箱 setter
- (void)setEmail:(NSString *)email;
// 邮箱 getter
- (NSString *)email;
// 电话号码 setter
- (void)setTelNumber:(NSInteger)telNumber;
// 电话号码 getter
- (NSInteger)telNumber;
// 显示联系人信息
- (void)show;
@end
第一个类的AddressPerson.m文件里面的内容:
#import "AddressPerson.h"
@implementation AddressPerson
// 带参初始化
- (instancetype)initWithName:(NSString *)name andTelNumber:(NSInteger)telNumber andEmail:(NSString *)email
{
self = [super init];
if (self) {
_name = name;
_telNumber = telNumber;
_email = email;
}
return self;
}
// 实例变量 姓名setter
- (void)setName:(NSString *)name;
{
_name = name;
}
// 姓名getter
- (NSString *)name
{
return _name;
};
// 地址 setter
- (void)setAddress:(NSString *)address
{
_address = address;
}
// 地址 getter
- (NSString *)address
{
return _address;
}
// 邮箱 setter
- (void)setEmail:(NSString *)eamil
{
_email = eamil;
}
// 邮箱 getter
- (NSString *)email
{
return _email;
}
// 电话号码 setter
- (void)setTelNumber:(NSInteger)telNumber
{
_telNumber = telNumber;
}
// 电话号码 getter
- (NSInteger)telNumber
{
return _telNumber;
}
// 显示信息
- (void)show
{
NSLog(@"姓名: %@ 电话号码: %ld" , _name , _telNumber );
}
-(NSString *)description
{
return [NSString stringWithFormat:@"姓名: %@\t电话号码: %ld" , _name , _telNumber];
}
@end
想必第一个类大家都会写,毕竟里面没有什么东西,下面是第二个类
即电话簿类:
AddressBook.h文件内容:
#import <Foundation/Foundation.h>
@class AddressPerson;
@interface AddressBook : NSObject
{
NSMutableDictionary *_contacts;
}
// contacts setter and getter
- (void)setContacts:(NSMutableDictionary *)contacts;
- (NSMutableDictionary *)contacts;
//利用正则表达式验证邮箱是否正确
+(BOOL)isValidateEmail:(NSString *)email;
// 添加新的联系人 如果姓名或电话号码为空,打印添加失败
- (void)addContact:(AddressPerson *)contact;
// 获取某个分组下得所有联系人
- (NSMutableArray *)getAllContactsByGroup:(NSString *)groupName;
// 根据电话号码搜索联系人
- (void)searchContactByTelNumber:(NSInteger)telNumber;
// 根据姓名删除联系人
- (void)deletContactByName:(NSString *)name;
// 联系⼈人按姓名排序,要求使⽤用block
- (NSArray *)sortedByName;
// 展示通讯录中的所有联系人
- (void)showAllContacts;
@end
相信上面的也不难写,主要是方法的声明下面是实现
AddressBook.m文件内容:
#import "AddressBook.h"
#import "AddressPerson.h"
@implementation AddressBook
// 初始化字典
- (instancetype)init
{
self = [super init];
if (self) {
_contacts = [NSMutableDictionary dictionary];
}
return self;
}
// contacts setter and getter
- (void)setContacts:(NSMutableDictionary *)contacts
{
_contacts = contacts;
}
- (NSMutableDictionary *)contacts
{
return _contacts;
}
//利用正则表达式验证
+(BOOL)isValidateEmail:(NSString *)email {
NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
return [emailTest evaluateWithObject:email];
}
// 添加新的联系人 如果姓名或电话号码为空,邮箱格式正确
- (void)addContact:(AddressPerson *)contact
{
// 添加联系人实质是:拿到联系人的首字母再按首字母分组,让后将联系人添加到这个组里面
if ([contact name] == 0) {
NSLog(@"姓名为空");
} else if ([contact telNumber] == 0) {
NSLog(@"电话号码为空");
} else if ([AddressBook isValidateEmail:[contact email]] == NO){
NSLog(@"邮箱格式不正确");
} else {
// 1.拿到联系人的姓名 并小写
NSString *name = [[contact name] lowercaseString];
// 2.取名字的首字母
NSString *first = [name substringToIndex:1];
// 3.取字典中的关键字关键字
NSArray *keys = [_contacts allKeys];
// 4.看有没有这个分组(关键字),如果有直接添加元素,如果没有先创建再添加
// 设定一个bool值来判定有没有这个key
BOOL isHaveThisGroup = NO;
// 快速遍历key(组名) 如果有则将其置为真
for (NSString *key in keys) {
if ([key isEqualTo:first]) {
isHaveThisGroup =YES;
break;
}
}
// 如果有组直接添加元素,如果没有先创建再添加
if (isHaveThisGroup == YES) {
// 有 取出这个组
NSMutableArray *minArray = _contacts[first];
//然后向组中添加联系人
[minArray addObject:contact];
} else {
// 没有这个组,字典中添加一个 键值对
// 1.为这个键值对的值设置为一个可变数组
NSMutableArray *minArray = [NSMutableArray array];
// 2、将联系人添加到这个小数组中--->value
[minArray addObject:contact];
// 3. 将这个键值对添加到字典中
[_contacts setObject:minArray forKey:first];
}
}
}
// 获取某个分组下得所有联系人
- (NSMutableArray *)getAllContactsByGroup:(NSString *)groupName
{
// 获取某个分组中的所有联系人 也就是取出这个键值对
// 要想取出这个键值对 就得 遍历所有的key 然后返回这个key 对应的value
// 创建一个数组接受value
// NSMutableArray *group = [NSMutableArray array];
// 1. 拿出字典中的所有key
NSArray *keys = [_contacts allKeys];
// 2.快速遍历key
for (NSString *key in keys) {
// 拿到这个key并并返回
if ([key isEqualTo:groupName]) {
// 取key 对应的value
return _contacts[key];
//group = [_contacts valueForKey:key];
}
}
return nil;
}
// 根据电话号码搜索联系人
- (void)searchContactByTelNumber:(NSInteger)telNumber
{
// 电话号码是联系人的一个属性 找电话号码--->联系人---->value数组里面--->value通过key找到
// 2.取字典中的所有key并遍历
NSArray *keys = [_contacts allKeys];
for (NSString *key in keys) {
// 拿到value 遍历value数组中的元素
for (AddressPerson *contact in _contacts[key]) {
// 拿到号码 , 显示联系人
if (telNumber == [contact telNumber]) {
[contact show];
return;
}
}
}
}
// 根据姓名删除联系人
- (void)deletContactByName:(NSString *)name
{
// 与电话号码搜索联系人相似
NSArray *keys = [_contacts allKeys];
for (NSString *key in keys) {
for (AddressPerson *contact in _contacts[key]) {
if ([[contact name] isEqualTo:name]) {
NSMutableArray *value = _contacts[key];
[value removeObject:contact];
return ;
}
}
}
}
// 联系⼈人按姓名排序,要求使⽤用block
- (NSArray *)sortedByName
{
// 定义一个可变数组 , 将所有的联系人都存到里面
NSMutableArray *allContacts = [[NSMutableArray alloc] init];
for (NSString *key in [_contacts allKeys]) {
for (AddressPerson *contact in _contacts[key]) {
[allContacts addObject:contact];
}
}
// 将这个数组按姓名进行升序排序 (block)
NSArray *array = [allContacts sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSString *name1 = [(AddressPerson *)obj1 name];
NSString *name2 = [(AddressPerson *)obj2 name];
return [name1 compare:name2];
}];
return array;
}
// 展示通讯录中的所有联系人
- (void)showAllContacts
{
// 1. 取出所有的key
NSArray *keys = [_contacts allKeys];
// 2、遍历key
for (NSString *key in keys) {
// 遍历 key 对应的value 并打印
for (AddressPerson *contact in _contacts[key]) {
[contact show];
}
}
}
搞定了,通过写通讯录,可以让我们把很多知识点综合起来使用。